有没有办法将Ruby on Rails中的几个where子句与内部if语句结合起来



我是新手,也是 rails 的新手。我目前正在尝试为我的培训项目的数据库(书籍(制作自己的搜索功能。我不想实现现有的搜索表单,因为我只想学习。到目前为止,它正在工作,但现在我添加了一个下拉菜单来选择比较符号。在此基础上,它应找到具有评级的书籍("==",">="或"<="(。

我尝试在整个 where 部分之前设置 if 子句,但这意味着我需要将整个 where 部分设置为 3 次。我希望有更短的方法来实现这一点?提前谢谢你!

def self.advanced_search(s_name, s_author, s_comp_sign, s_rating)  
  where("lower(name) LIKE ?", "%#{s_name}%").  
  where("lower(author) LIKE ?", "%#{s_author}%").  
  where(:rating == s_rating) #if s_comp_sign == "="
  where(:rating >= s_rating) #if s_comp_sign == ">"
  where(:rating <= s_rating) #if s_comp_sign == "<"
end

由于您需要根据用户选择的运算符对同一字段进行查询,因此您可以这样做:

方法一:

添加一个方法,该方法将根据您从视图中收到的内容返回正确的运算符:

def operator_chosen(op)
  case op
  when '>'
    '>='
  when '<'
    '<='
  when '='
    '=='
  else
    '<>'
  end
end
我添加了不等于作为默认情况

,您可以使用等于作为默认情况。然后你可以这样做:

where("rating #{operator_chosen(s_comp_sign)} s_rating") if s_comp_sign.present?

方法2:

您也可以使用三元运算符来做到这一点,但代码不会那么可读,它看起来很复杂,如下所示:

op = (s_comp_sign == '>' ? '>=' : (s_comp_sign == '<' ? '<=' : '=='))

这里的默认值将==,然后这可以用作:

where("rating #{op} s_rating") if s_comp_sign.present?

避免这种情况的方法之一是在查询数据之前创建在字符串中存储条件。

例如: rating_condition = "rating " + s_comp_sign + " ?"

然后像这样查询: where("lower(name) LIKE ?", "%#{s_name}%").
where("lower(author) LIKE ?", "%#{s_author}%").
where(rating_condition,s_rating)

最新更新