0

RailsCast #154 on Polymorphic Associationに従って、次のように移行をセットアップしました。

# db/migrate/20130719120000_create_comments.rb
class CreateComments < ActiveRecord::Migration
  def change
    create_table :comments do |t|
      t.string :subject
      t.text :message
      t.belongs_to :commentable, polymorphic: true    
      t.timestamps
    end
    add_index :comments, [:commentable_id, :commentable_type]
  end
end

モデルは次のようになります。

# app/models/comment.rb
class Comment < ActiveRecord::Base
  attr_accessible :message, :subject
  belongs_to :commentable, polymorphic: true
  counter_culture :commentable # This does not work, read below.
end

コメントは複数のモデルに設定できます。以下に 1 つの例を示します。

# app/models/product.rb
class Product < ActiveRecord::Base    
  has_many :comments, as: :commentable
  attr_accessible :name
end

これはうまくいきます。


ここで、コメントの数を単純にカウントするgem counter_culture ( Commentモデルでわかるように) も使用します。関連付けられたモデル (この場合はProduct ) のプロパティとしてカウント値を格納します。コメントモデルをポリモーフィズムに切り替える前に、統合は機能していました。

に変更counter_culture :commentableするcounter_culture :productと、次のエラー メッセージが表示されます。

NoMethodError: undefined method `product' for #<Comment:0x0000000531cdb0>
    from /home/jjd/.rvm/gems/ruby-1.9.3-p448@demoapp/gems/activemodel-3.2.13/lib/active_model/attribute_methods.rb:407:in `method_missing'
    from /home/jjd/.rvm/gems/ruby-1.9.3-p448@demoapp/gems/activerecord-3.2.13/lib/active_record/attribute_methods.rb:149:in `method_missing'
    from /home/jjd/.rvm/gems/ruby-1.9.3-p448@demoapp/gems/counter_culture-0.1.12/lib/counter_culture.rb:301:in `foreign_key_value'
    from /home/jjd/.rvm/gems/ruby-1.9.3-p448@demoapp/gems/counter_culture-0.1.12/lib/counter_culture.rb:243:in `change_counter_cache'
    from /home/jjd/.rvm/gems/ruby-1.9.3-p448@demoapp/gems/counter_culture-0.1.12/lib/counter_culture.rb:196:in `block (2 levels) in _update_counts_after_create'
    from /home/jjd/.rvm/gems/ruby-1.9.3-p448@demoapp/gems/counter_culture-0.1.12/lib/counter_culture.rb:194:in `each'
    from /home/jjd/.rvm/gems/ruby-1.9.3-p448@demoapp/gems/counter_culture-0.1.12/lib/counter_culture.rb:194:in `block in _update_counts_after_create'
    from /home/jjd/.rvm/gems/ruby-1.9.3-p448@demoapp/gems/counter_culture-0.1.12/lib/counter_culture.rb:186:in `call'
    from /home/jjd/.rvm/gems/ruby-1.9.3-p448@demoapp/gems/counter_culture-0.1.12/lib/counter_culture.rb:186:in `_wrap_in_counter_culture_active'
    from /home/jjd/.rvm/gems/ruby-1.9.3-p448@demoapp/gems/counter_culture-0.1.12/lib/counter_culture.rb:193:in `_update_counts_after_create'
    from /home/jjd/.rvm/gems/ruby-1.9.3-p448@demoapp/gems/activesupport-3.2.13/lib/active_support/callbacks.rb:405:in `_run__2202164684578441182__create__891150410440608527__callbacks'
    from /home/jjd/.rvm/gems/ruby-1.9.3-p448@demoapp/gems/activesupport-3.2.13/lib/active_support/callbacks.rb:405:in `__run_callback'
    from /home/jjd/.rvm/gems/ruby-1.9.3-p448@demoapp/gems/activesupport-3.2.13/lib/active_support/callbacks.rb:385:in `_run_create_callbacks'
    from /home/jjd/.rvm/gems/ruby-1.9.3-p448@demoapp/gems/activesupport-3.2.13/lib/active_support/callbacks.rb:81:in `run_callbacks'
    from /home/jjd/.rvm/gems/ruby-1.9.3-p448@demoapp/gems/activerecord-3.2.13/lib/active_record/callbacks.rb:268:in `create'
    from /home/jjd/.rvm/gems/ruby-1.9.3-p448@demoapp/gems/activerecord-3.2.13/lib/active_record/persistence.rb:348:in `create_or_update'

これは基本的に_update_counts_after_create192を指します。

# Source: https://github.com/magnusvk/counter_culture/blob/master/lib/counter_culture.rb#L192
# called by after_create callback
def _update_counts_after_create
  _wrap_in_counter_culture_active do
    self.class.after_commit_counter_cache.each do |hash|
      # increment counter cache
      change_counter_cache(hash.merge(:increment => true))
    end
  end
end

hashwhilecounter_culture :commentableが設定されていることを調べると、 Productモデル:relationに解決されていることがわかります。

{:relation=>[:commentable], :counter_cache_name=>"comments_count", :column_names=>nil, :foreign_key_values=>nil}

これは、リレーションが割り当てられている29 行目で行う必要があると思います。

:relation => relation.is_a?(Enumerable) ? relation : [relation],

製品モデルrelationを解決するためのポリモーフィック アソシエーションであるかどうかをテストするにはどうすればよいですか?

4

1 に答える 1