简体   繁体   English

按视图类型过滤多态关联

[英]Filtering polymorphic association by type for a view

I have a polymorphic association that looks like this: 我有一个看起来像这样的多态关联:

class Event < ActiveRecord::Base
  belongs_to :eventable, :polymorphic => true
end

With a bunch of types: 有很多类型:

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

And so on. 等等。

Here's the other end of the relationship: 这是关系的另一端:

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

I want to grab all the events of all types that belong to a person for display in a single view. 我想获取属于一个人的所有类型的所有事件以在单个视图中显示。 Here's what I'm doing: 这是我在做什么:

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

I need to filter by type because the view is going to be displaying type-specific attributes in each section of the view. 我需要按类型进行过滤,因为视图将在视图的每个部分中显示特定于类型的属性。

Question: Should this logic of filtering out the collection of events by type into their own type-specific arrays exist in the controller? 问题:控制器中是否应存在按类型将events集合过滤到其自己的特定于类型的数组中的逻辑? Or elsewhere? 还是其他地方? Perhaps the model? 也许是模型?

I was reluctant to just pass @events to the view and have the type test happen in the view itself. 我不愿意仅将@events传递给视图,并在视图本身中进行类型测试。 That seemed wrong. 好像错了

You can use the @events query to create a subquery without having to iterate (I'm assuming you have the inverse has_many :events, as: :eventable in each of your other models): 您可以使用@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.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM