我按照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
一个评论可以设置多个模型,这里是一个例子:
# app/models/product.rb
class Product < ActiveRecord::Base
has_many :comments, as: :commentable
attr_accessible :name
end
这工作得很好。
现在我还使用gem counter_culture(正如您在评论模型中看到的那样),它简单地计算评论的数量。它将计数值存储为关联模型的属性,在本例中为Product。在我将Comment模型切换为多态性之前,集成工作。
当我更改为时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_create
第192 行。
# 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
当我检查hash
whilecounter_culture :commentable
设置时,我可以看到必须将:relation
其解析为Product模型。
{:relation=>[:commentable], :counter_cache_name=>"comments_count", :column_names=>nil, :foreign_key_values=>nil}
我认为这应该在分配关系的第 29 行中完成。
:relation => relation.is_a?(Enumerable) ? relation : [relation],
如何测试是否relation
是多态关联来解析Product模型?