2015-06-29 92 views
1

我有一個多態關聯,看起來像這樣:過濾態關聯的類型視圖

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

我想如果弄清楚你可能會在模型層中做一些奇怪的事情。你可以添加「Eventable」和「Person」的相關摘錄嗎?我不完全確定這些之間的關聯。 – lime

+0

另外,你覺得吃飯,午睡,情緒和筆記爲_events_?還是有什麼更多的事件和事件'分開? – lime

+0

能否請你展示什麼寫在Eventable ... –

回答

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. 
+0

哇,這比我的代碼更簡潔。不確定'group_by'的效率與我正在做的事情有關,但這不是現在的問題。問:如果要從多個控制器使用它,你會在「事件」中將它分解成一個方法嗎? '@eventables [「飯」] [0: –

+0

而且,請注意,在你的榜樣,'@ eventables'實際上是'Events' --ie哈希,直到你做這樣的事情,你不能訪問特定類型的屬性] .eventable.food' –

+0

你非常正確,我很抱歉,我來得太快。我已經更新了我的答案。 – smathy