2013-03-21 91 views
2

我有幾個共享問題的模型。每個模型都會傳入一個散列,這意味着要處理他們使用這個問題的方式上的細微差別。我通過一個類的方法通過散列像這樣:Rails:將變量從類方法傳遞到實例方法

add_update_to :group, :user 

的關心完整的代碼是:

module Updateable 
    extend ActiveSupport::Concern 

    attr_accessor :streams 

    module ClassMethods 
    def add_updates_to(*streams) 
     @streams = streams 
    end 
    end 

    module InstanceMethods 
    def update_streams 
     @streams.collect{|stream| self.public_send(stream)} 
    end 
    end 

    included do 
    has_one :update, :as => :updatable 

    after_create :create_update_and_history 
    end 

    private 
    def create_update_and_history 
     update = self.create_update(:user_id => User.current.id) 
     self.update_streams.each do |stream| 
     stream.histories.create(:update_id => update.id) 
     end 
    end 
end 

大部分代碼的工作,但我有從通過哈希麻煩該類到一個實例。目前,我試圖通過創建一個虛擬屬性來實現這種效果,將散列傳遞給屬性,然後在實例中進行檢索。這不僅感覺不舒服,而且不起作用。我假設它不起作用,因爲@streams是一個實例變量,所以類方法add_update_to不能實際設置它?

無論如何,有沒有更好的方法來解決這個問題?

回答

3

你也許可以在這裏使用類變量,但是由於它們的不可預測性,這些在Ruby社區中是非常令人討厭的。需要記住的是,Ruby中的類實際上也是類的實例,並且可以擁有自己的實例變量,這些變量只能被自己訪問,並且不能被其實例訪問(如果以任何方式清除的話)。

在這種情況下,要定義行爲,而不是數據,所以我覺得既不instance和類變量是合適的。相反,我認爲最好的方法是直接在類方法中定義的實例方法,像這樣:

module Updateable 
    extend ActiveSupport::Concern 

    module ClassMethods 
    def add_updates_to(*streams) 
     define_method :update_streams do 
     streams.collect {|stream| public_send(stream) } 
     end 
    end 
    end 
end 

BTW,沒有這裏涉及到散列,所以我不知道你指的是什麼。 *streams將您的參數收集到數組中。

+0

優秀的迴應。它的工作原理,並感謝您花時間解釋您的答案。不過,有一件事我不明白,爲什麼你不必在'public_send(stream)'上調用'self'。 「自我」暗含了什麼? – nullnullnull 2013-03-21 03:04:04

+1

是的,「自我」通常是可選的。在一個實例方法中,任何未明確發送給另一個對象的方法調用會轉到「self」。 – 2013-03-21 03:43:33

相關問題