我有一个多态关联,如下所示:
class Event < ActiveRecord::Base
belongs_to :eventable, :polymorphic => true
end
有很多类型:
class Nap < ActiveRecord::Base
include Eventable
end
class Meal < ActiveRecord::Base
include Eventable
end
module Eventable
def self.included(base)
base.class_eval do
has_one :event, :as => :eventable, :dependent => :destroy
accepts_nested_attributes_for :event, :allow_destroy => true
scope :happened_at, -> (date) {
where("events.happened_at >= ? AND events.happened_at <= ?",
date.beginning_of_day, date.end_of_day).order("events.happened_at ASC")
}
base.extend(ClassMethods)
end
end
module ClassMethods
define_method(:today) do
self.happened_at(Date.today)
end
end
end
等等。
这是关系的另一端:
class Person < ActiveRecord::Base
has_many :events
has_many :meals, {
:through => :events,
:source => :eventable,
:source_type => "Meal"
}
has_many :naps, {
:through => :events,
:source => :eventable,
:source_type => "Nap"
}
has_many :moods, {
:through => :events,
:source => :eventable,
:source_type => "Mood"
}
has_many :notes, {
:through => :events,
:source => :eventable,
:source_type => "Note"
}
...
end
我想抓住属于一个人的所有类型的所有事件,以便在一个视图中显示。这就是我正在做的事情:
def show
@events = Event.by_person(@person).happened_at(date)
@meals, @naps, @moods, @notes = [], [], [], [], []
@events.each do |e|
@meals << e.eventable if e.eventable_type == 'Meal'
@naps << e.eventable if e.eventable_type == 'Nap'
@moods << e.eventable if e.eventable_type == 'Mood'
@notes << e.eventable if e.eventable_type == 'Note'
end
end
我需要按类型过滤,因为视图将在视图的每个部分中显示特定于类型的属性。
问题:控制器中是否存在将类型events
的类型过滤到他们自己的类型特定数组中的逻辑?或其他地方?也许是模特?
我不愿意将@events
传递给视图,并在视图中进行类型测试。这似乎不对。
答案 0 :(得分:1)
您可以使用@events
查询创建子查询而无需迭代(我假设您在其他每个模型中都有反has_many :events, as: :eventable
):
@events = Event.by_person(@person).happened_at(date)
@meals = Meal.joins(:event).where events: { id: @events }
@naps = Nap.joins(:event).where events: { id: @events }
# etc.