【问题标题】:Is there a way to combine several where clauses with inside if-statements in Ruby on Rails?有没有办法在 Ruby on Rails 中将几个 where 子句与内部 if 语句结合起来?
【发布时间】:2019-10-18 13:33:17
【问题描述】:

我是新来的,也是 Rails 的新手。我目前正在尝试为我的培训项目的数据库(书籍)创建自己的搜索功能。我不想实现现有的搜索表单,因为我只想学习。 到目前为止它正在工作,但现在我添加了一个下拉菜单来从中选择一个比较符号。基于此,它会找到带有评级(“==”、“>=”或“

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

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

【问题讨论】:

  • q = M.where(a).where(b) 等价于q = M.where(a); q = q.where(b)

标签: ruby-on-rails if-statement where


【解决方案1】:

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

方法一:

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

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?

方法二:

你也可以使用三元运算符,但是代码不会那么可读,看起来很复杂,像这样:

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

这里默认为==,然后可以用作:

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

【讨论】:

    【解决方案2】:

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

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

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

    【讨论】:

    • 字符串插值而不是加法怎么样?此外,看起来您可能需要在该插值字符串中使用 =...
    猜你喜欢
    • 1970-01-01
    • 2015-07-11
    • 1970-01-01
    • 1970-01-01
    • 2023-03-26
    • 1970-01-01
    • 2020-08-03
    • 2022-12-06
    • 2021-01-31
    相关资源
    最近更新 更多