多态关系和计数器缓存

时间:2012-03-21 17:11:20

标签: ruby-on-rails ruby-on-rails-3 polymorphic-associations

所以我有一个带有2个不同模型的应用程序,评论和回复,每个都可以同意或不同意,所以我有一个名为Emotion的多态模型。这是我的代码:

class Comment < ActiveRecord::Base
  belongs_to :user
  has_many :replies
  has_many :emotions, :as => :emotionable
end



class Reply < ActiveRecord::Base
  belongs_to :user
  belongs_to :comment
  has_many :emotions, :as => :emotionable
end

class Emotion < ActiveRecord::Base
  belongs_to :emotionable, :polymorphic => :true  
end

所以这一切都运行正常,但我需要为Comment和Reply添加一个计数器缓存,以获得每个对象的Agrees和Disagree的大小。在所有文档中,它都有使用正常多态关联进行计数器缓存的示例,而不是具有额外条件的计数缓存。作为参考,Emotion的模式如下所示:

create_table "emotions", :force => true do |t|
  t.integer  "user_id"
  t.string   "emotion"
  t.integer  "emotionable_id"
  t.string   "emotionable_type"
  t.datetime "created_at",       :null => false
  t.datetime "updated_at",       :null => false
end

TL:DR - 我需要能够通过计数器缓存在多态关联上调用@commet.agrees_count,@ comment.disagrees_count,@ reply.agrees_count和@ reply.disagrees_count。因此,评论和回复将需要2个计数器缓存。

3 个答案:

答案 0 :(得分:6)

您可能希望将计数器缓存属性添加到关联类中的attr_readonly列表中(例如,类Post; attr_readonly:comments_count; end)。 http://apidock.com/rails/ActiveRecord/Associations/ClassMethods/belongs_to

:polymorphic

    Specify this association is a polymorphic association by passing true. 
    Note: If you’ve enabled the counter cache, then you may
    want to add the counter cache attribute to the attr_readonly list in
    the associated classes 
    (e.g. class Post; attr_readonly :comments_count; end).

答案 1 :(得分:5)

我的建议是在after_commit回调中手动递增或递减计数器缓存,以便您可以测试记录是否持久化并在事务之外更新。这是因为它会使您的代码更加明确,并且在缓存更新或失效的方式和时间方面不那么神秘。

如果您希望在某些用户同意或不同意评论(例如业力系统)时为某些用户提供更多权限,那么手动更新缓存会为您提供额外的灵活性。

答案 2 :(得分:3)

“多态关系和反缓存”无关,它与Multiple counter_cache in Rails model

有关。

顺便说一下,对于多态关系和反缓存&#39;

class Code < ActiveRecord::Base
  has_many :notes, :as => :noteable
end

class Issue < ActiveRecord::Base
  has_many :notes, :as => :noteable
end

class Note < ActiveRecord::Base
  belongs_to :noteable, polymorphic: true, count_cache: :noteable_count
end

在您的表格&#39;问题&#39;中,您应该有列&#39; noteable_count&#39;,与您的表格相同&#39;