在我的Rails 3.2应用程序中,连接器has_many事件。
要获取某个连接器的所有事件,我可以这样做: (在控制台中)
c = Connector.find(1) # c.class is Connector(id: integer, name: string, ...
i = c.incidents.all # all good, lists incidents of c
但是如何才能获得许多连接器的所有事件?
c = Connector.find(1,2) # works fine, but c.class is Array
i = c.incidents.all #=> NoMethodError: undefined method `incidents' for #<Array:0x4cc15e0>
应该很容易!但我不明白!
这是我的statistics_controller.rb中的完整代码
class StatisticsController < ApplicationController
def index
@connectors = Connector.scoped
if params['connector_tokens']
logger.debug "Following tokens are given: #{params['connector_tokens']}"
@connectors = @connectors.find_all_by_name(params[:connector_tokens].split(','))
end
@start_at = params[:start_at] || 4.weeks.ago.beginning_of_week
@end_at = params[:end_at] || Time.now
#@time_line_data = Incident.time_line_data( @start_at, @end_at, 10) #=> That works, but doesn’t limit the result to given connectors
@time_line_data = @connectors.incidents.time_line_data( @start_at, @end_at, 10) #=> undefined method `incidents' for #<ActiveRecord::Relation:0x3f643c8>
respond_to do |format|
format.html # index.html.haml
end
end
end
大!使用下面的代码,我得到一个包含给定连接器的所有事件的数组。
c = Connector.find(1,2)
i = c.map(&:incidents.all).flatten
但是理想我想获得一个Active Records对象而不是数组,因为我想调用它上面的where(),你可以在下面的方法time_line_data
中看到。
我可以通过阵列实现我的目标,但我需要改变整个战略......
这是事件模型models / incidents.rb中的time_line_data()
def self.time_line_data(start_at = 8.weeks.ago, end_at = Time.now, lim = 10)
total = {}
rickshaw = []
arr = []
inc = where(created_at: start_at.to_time.beginning_of_day..end_at.to_time.end_of_day)
# create a hash, number of incidents per day, with day as key
inc.each do |i|
if total[i.created_at.to_date].to_i > 0
total[i.created_at.to_date] += 1
else
total[i.created_at.to_date] = 1
end
end
# create a hash with all days in given timeframe, number of incidents per day, date as key and 0 as value if no incident is in database for this day
(start_at.to_date..end_at.to_date).each do |date|
js_timestamp = date.to_time.to_i
if total[date].to_i > 0
arr.push([js_timestamp, total[date]])
rickshaw.push({x: js_timestamp, y: total[date]})
else
arr.push([js_timestamp, 0])
rickshaw.push({x: js_timestamp, y: 0})
end
end
{ :start_at => start_at,
:end_at => end_at,
:series => rickshaw #arr
}
end
答案 0 :(得分:2)
参考: - map
c = Connector.find(1,2)
i = c.map(&:incidents.all).flatten
答案 1 :(得分:2)
由于您似乎只对时间线数据感兴趣,您可以进一步扩展之前给出的地图示例:
@time_line_data = @connectors.map do |connector|
connector.incidents.map do |incident|
incident.time_line_data(@start_at, @end_at, 10)
end
end
这将映射/收集time_line_data方法调用的所有返回值,用于连接器集合中的所有事件。