Rails 3.2 – 未定义的方法`where’for#<Array:… – Model.where()的查询

我试图将给定Header中的字段与Alarm模型中的其他字段进行比较。 正如您在代码中看到的,我以3个不同的步骤过滤警报。 前2个工作完美。 但是,最后一个不起作用。 它说:

 undefined method `where' for #<Array:... 

据我所知.where是一个与数组一起使用的类方法。 为什么不在这里工作? 我也试过.find_all_by和不同的东西……但无济于事。

 @header = Header.find(1) # Extracts those alarms that are ACTIVE and have something in common with the tittles @alarmsT = Alarm.activated.where("keyword in (?)", [@header.title_es, @header.title_en, @header.title_en]) # Extracts alarms when Header has at least the same categories as an alarm @alarmsT = @alarmsT.select do |alarm| @header.category_ids.all?{|c| alarm.category_ids.include? c } end // this is the one that does NOT work # Extract alarms which share the same location as Header.events' town @alarmsF = [] @header.events.each do |e| @alarmsF = @alarmsF + @alarmsT.where("alarms.location LIKE ?", e.town) end 

任何帮助发现我错过的东西非常感谢。 谢谢

在第一行中,您已成功返回@alarmsTActiveRecordRelation对象

 # Extracts those alarms that are ACTIVE and have something in common with the tittles @alarmsT = Alarm.activated.where("keyword in (?)", [@header.title_es, @header.title_en, @header.title_en]) 

此时,您可以在@alarmsT上应用其他.where(...)方法,条件或范围,以进一步构建ARel表达式并返回结果。

但是,然后在此关系上运行filter,将@alarmsT转换为Array实例

 # Extracts alarms when Header has at least the same categories as an alarm @alarmsT = @alarmsT.select do |alarm| @header.category_ids.all?{|c| alarm.category_ids.include? c } end 

您不能再构建ARel表达式,因为Array不知道您的ARel的.where .where(...)方法,或任何Alarm模型的范围或属性。 这就是为什么在下面的代码中你得到undefined method 'where' for # error - 你在一个Array实例上调用.where() ; 一种不存在的方法。

 @alarmsF = [] @header.events.each do |e| @alarmsF = @alarmsF + @alarmsT.where("alarms.location LIKE ?", e.town) end 

您可以通过不按类别ID进行过滤而使用连接来解决此问题。 构建这样的连接(以validation相关表/列中至少存在一个值的子集)在很容易通过谷歌和StackOverflow找到的地方记录。

就像@Deefour所说,使用select你在Array中收集数据而不是ActiveRecord::Relation对象。

您确定需要LIKE查询吗? 通过观察它我猜你可以用一个简单的直接比较。 如果我的假设是正确的,您可以重新排列代码的最后部分:

 @alarmsF = [] towns_from_events = @header.events.collect(&:town) @alarmsT.each do |alarmsT| @alarmsF << alarmsT if towns_from_events.include?(alarmsT.location) end