我正在尝试将给定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
任何帮助发现我所缺少的东西都非常感激。感谢
答案 0 :(得分:6)
在第一行中,您成功返回了ActiveRecordRelation
@alarmsT
个对象
# 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])
此时,您可以在.where(...)
上应用其他@alarmsT
方法,条件或范围,以进一步构建ARel表达式并返回结果。
但是,您可以对此关系运行过滤器,将@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(...)
方法,或任何Alarm
模型的范围或属性。这就是为什么在下面的代码中您收到undefined method 'where' for #<Array:...
错误 - 您在.where()
的实例上调用Array
;一种不存在的方法。
@alarmsF = []
@header.events.each do |e|
@alarmsF = @alarmsF + @alarmsT.where("alarms.location LIKE ?", e.town)
end
您可以通过不按类别ID进行过滤而使用连接来解决此问题。构建这样的连接(以验证相关表/列中至少存在一个值的子集)在很容易通过谷歌和StackOverflow找到的地方进行了详细记录。
答案 1 :(得分:3)
就像@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