2013-03-21 2 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 на самом деле также являются экземплярами классов и могут иметь свои собственные переменные экземпляра, которые доступны только для себя и недоступны для их экземпляров (если это так или иначе ясно).

В этом случае, вы определяете поведение, а не данные, поэтому я думаю, что ни переменные экземпляра, ни класса подходят. Вместо этого, я думаю, вам лучше определить методы экземпляра непосредственно в методе класса, например:

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

Отличный отклик. Он работает, и благодарим вас за то, что нашли время, чтобы объяснить ваш ответ. Однако я не понимаю, почему вам не нужно называть 'self' на' public_send (stream) '. Почему-то подразумевается 'self'? – nullnullnull

+1

Да, 'self' часто является необязательным. В методе экземпляра любой вызов метода, явно не отправленный другому объекту, переходит в 'self'. –

Смежные вопросы