2

私は懸念を共有するいくつかのモデルを持っています。各モデルはハッシュを渡します。ハッシュは、懸念事項の使用方法のわずかな違いを処理することを目的としています。次のようなクラスメソッドを介してハッシュを渡します。

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で実際に設定することはできませんか?

いずれにせよ、この問題に取り組むためのより良い方法はありますか?

4

1 に答える 1

4

ここでクラス変数を使用することもできますが、Ruby コミュニティでは、その予測不可能な性質のために非常に嫌われています。覚えておくべきことは、Ruby のクラスは実際にはクラスのインスタンスでもあり、それ自体にのみアクセス可能で、そのインスタンスにはアクセスできない独自のインスタンス変数を持つことができるということです (何らかの形で明確な場合)。

この場合、dataではなくbehaviorを定義しているので、インスタンス変数もクラス変数も適切ではないと思います。代わりに、次のように、インスタンス メソッドをクラス メソッド内で直接定義するのが最善の策だと思います。

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引数を配列に収集します。

于 2013-03-21T02:42:19.043 に答える