在查询中有条件地添加OR条件

时间:2013-12-24 09:01:31

标签: ruby-on-rails activerecord

订单表有几列,比如电子邮件,电话和地址。

用户提供电子邮件/电话/地址,其中任何一个都可以是空字符串(已编辑)。

如何生成OR查询,因此如果任何列匹配,则返回记录?

唯一的问题是,如果提供的任何值为nil或空,则会被忽略。

我能够使用Arel进行以下操作:

email = params[:email]
tel = params[:tel]
address =  params[:address]

t = Order.arel_table
sq = t[:email].eq(email) if email.present?
sq = sq.or(t[:phone].eq(phone)) if phone.present?
sq = sq.or(t[:phone].eq(address)) if address.present?
Order.where( sq )

但是,如果电子邮件为零,则会出错,因为sq不会实例化。

我想阻止构造sql字符串,我使用Squeel gem。

4 个答案:

答案 0 :(得分:2)

你可以把

Order.where("email=? or tel= ? or address=?", params[:email], params[:tel], params[:address])

答案 1 :(得分:1)

您可以Ick's检查您的参数是否为零。所以请阅读有关Ick gem的内容并按照其中给出的步骤进行操作,然后您可以在以下情况下使用它:

params[:email].maybe
params[:tel].maybe
params[:address].maybe

希望,这就是你要找的东西。

答案 2 :(得分:1)

请试试

where_condition = "true"
where_condition += "OR email = '#{params[:email]}'" if params[:email].present?  
where_condition += "OR tel = '#{params[:tel]}'" if params[:tel].present?
where_condition += "OR address = '#{params[:address]}'" if params[:address].present?

Order.where(where_condition)

答案 3 :(得分:0)

为了防止零或空字符串,我终于得到了以下内容:

t = Order.arel_table

conditions = [:email, :phone, :address].map{|attr|
  attr_value = params[attr]
  if attr_value.present?
    t[attr].eq(attr_value)
  else
    nil
  end
}.compact

if conditions.empty?
  Order.where('1=0')
else
  Order.where( conditions.inject{|c, cc| c.or(cc).expr} )
end

丑陋但灵活。