多态关联和计数缓存

13

我有一个包含两种不同模型的应用程序,即评论(Comments)和回复(Replies),每个模型都可以被赞同或反对。因此,我创建了一个多态模型称为 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

这一切都很好,但我需要为评论和回复添加计数器缓存,以便获取每个对象的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

简而言之,我需要能够通过计数器缓存在多态关联上调用@comment.agrees_count、@comment.disagrees_count、@reply.agrees_count和@reply.disagrees_count。因此,评论和回复将需要2个计数器缓存。

3个回答

8
我建议您在after_commit回调中手动增加或减少计数器缓存,这样您就可以测试记录是否已保存,并且在事务之外更新。这是因为它会使您的代码更加明确, less有神秘感,不清楚缓存何时何地被更新或失效。
此外,手动更新缓存还为您提供了额外的灵活性,例如,如果您想在评论时赋予某些用户更多权限(例如karma系统)。

8

你可能想要将计数器缓存属性添加到相关类的attr_readonly列表中(例如,class 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).

8
这是关于Rails模型中多个counter_cache的问题,与“多态关系和计数缓存”无关。
顺便说一下,“多态关系和计数缓存”是什么。
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, counter_cache: :noteable_count
end

在你的表 'issues' 中,应该有与你的表 'codes' 相同的列 'noteable_count'。

2
这应该在Rails 5中工作,但在此之前的版本中不起作用。 (https://github.com/rails/rails/issues/16407) - iconoclast
是的,没错 - 无论你要计算什么类型的关系,只需指定计数器所在的列并庆祝即可! - Alexander Gorg
1
你的类型出错了。应该是 counter_cache: :noteable_count - Yshmarov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接