Rails:将变量从类方法传递到实例方法

时间:2013-03-21 02:17:44

标签: ruby-on-rails variables methods

我有几个共同关注的模型。每个模型都传递一个哈希,这意味着处理他们使用关注点的方式的微小差异。我通过类方法传递哈希:

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

这些代码大部分都可以工作,但是我在将哈希从类传递给实例时遇到了麻烦。目前,我正在尝试通过创建虚拟属性,将哈希值传递给属性,然后在实例中检索它来实现此效果。这不仅感到hacky,而且不起作用。我假设它不起作用,因为@streams是一个实例变量,所以类方法add_update_to实际上无法设置它?

无论如何,有没有更好的方法来解决这个问题?

1 个答案:

答案 0 :(得分:4)

你可能在这里使用类变量,但由于它们不可预测的性质,它们在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
顺便说一下,这里没有哈希,所以我不确定你指的是什么。 *streams将您的参数收集到数组中。