在模型中创造条件

时间:2012-12-02 22:15:03

标签: ruby-on-rails ruby-on-rails-3 ruby-on-rails-3.2

我试图创造我的搜索条件,但我有一些麻烦。

这是我想要创建的方法。

def self.searchadv(title, place, category, date)
    !title.blank? ? conditions = ['title LIKE ?', "%#{title}%"] : conditions = []
    if conditions
        !place.blank? ? conditions << [' AND place LIKE ?', "%#{place}%"] :  conditions << []
        !place.blank? ? conditions << [' AND category LIKE ?', "%#{place}%"] :  conditions << []
        !place.blank? ? conditions << [' AND date LIKE ?', "%#{place}%"] :  conditions << []
    else 
        !place.blank? ? conditions << [' place LIKE ?', "%#{place}%"] :  conditions << []
        !place.blank? ? conditions << [' category LIKE ?', "%#{place}%"] :  conditions << []
        !place.blank? ? conditions << [' date LIKE ?', "%#{place}%"] :  conditions << []
    end
    find(:all, :conditions => conditions)
end

它工作,greate直到我尝试附加place参数并且我收到此错误

  

错误的绑定变量数(4为1):标题LIKE?

如果我删除它:

if conditions
    !place.blank? ? conditions << [' AND place LIKE ?', "%#{place}%"] :  conditions << []
    !place.blank? ? conditions << [' AND category LIKE ?', "%#{place}%"] :  conditions << []
    !place.blank? ? conditions << [' AND date LIKE ?', "%#{place}%"] :  conditions << []
else 
    !place.blank? ? conditions << [' place LIKE ?', "%#{place}%"] :  conditions << []
    !place.blank? ? conditions << [' category LIKE ?', "%#{place}%"] :  conditions << []
    !place.blank? ? conditions << [' date LIKE ?', "%#{place}%"] :  conditions << []
end

一切都很好,但是我需要其他选项才能创建我的搜索,而且我没有说明为什么错误出现在“LiKE”中

有人可以帮我吗?

提前致谢!

2 个答案:

答案 0 :(得分:0)

这非常难看,难以阅读/调试,因而容易出错

def self.searchadv(title, place, category, date)
  conditions              = {}
  conditions[:title]      = "%#{title}%" if title.present?

  if place.present?
    conditions[:place]    = "%#{place}%"
    conditions[:category] = "%#{category}%"
    conditions[:date]     = "%#{date}%"
  end

  where(conditions)
end

编辑正如OP所指出的,上面不允许通配符匹配。以下使用ARel的matches方法来实现此目的。

def self.searchadv(title, place, category, date)
  offers     = self.arel_table
  predicates = []

  predicates << offers[:title].matches("%#{title}%") if title.present?

  if place.present?
    predicates << offers[:place].matches("%#{place}%")
    predicates << offers[:category].matches("%#{category}%")
    predicates << offers[:date].matches("%#{date}%")
  end

  if predicates.size > 1
    first = predicates.shift
    conditions = Arel::Nodes::Grouping.new(predicates.inject(first) {|memo, expr| Arel::Nodes::And.new(memo, expr)})
  else
    conditions = predicates.first
  end

  where(conditions).to_a
end

答案 1 :(得分:0)

我是第一次尝试保留你的代码并且只是尝试纠正它,但是有很多坏事:)这就是我将如何保持与你使用相同的结构(但也许它是更好地使用条件Hash,如@ Deefour的建议):

def self.searchadv(title, place, category, date)
  cond_ary = []
  cond_values = []
  unless title.blank?
    cond_ary << 'title LIKE ?'
    cond_values << "%#{title}%"
  end
  unless place.blank?
    cond_ary << 'place LIKE ? AND category LIKE ? AND date LIKE ?'
    cond_values.push("%#{place}%", "%#{place}%", "%#{place}%")
  end
  conditions = [ cond_ary.join(' AND ') ] + cond_values
  find(:all, :conditions => conditions)
end

我可以建议您研究条件数组应该是什么样子,然后在ruby控制台中使用数组。例如。看看数组如何发生,例如ary << 1ary << [1,2,3]ary.concat([1,2,3])ary.push(1,2,3)等。

当你做的时候

expr ? x = 1 : x = 2

最好使用

x = expr ? 1 : 2