我在posts_count模型中添加了一个Tag列:
create_table "tags", :force => true do |t|
t.string "name"
t.datetime "created_at", :null => false
t.datetime "updated_at", :null => false
t.integer "posts_count", :default => 0, :null => false
end现在,我试图根据这个问题(为多到多的关联创建计数器缓存)为它们构建一个计数器缓存:Counter cache for a model with a many-to-many association。
post.rb:
private
after_create :increment_tag_counter_cache
after_destroy :decrement_tag_counter_cache
def increment_tag_counter_cache
Tag.increment_counter(:posts_count, self.taggings.tag.id)
end
def decrement_tag_counter_cache
Tag.decrement_counter(:posts_count, self.taggings.tag.id)
end但是当我创建一个Post时,我得到了这个
undefined method `tag' for []:ActiveRecord::Relation我认为这个部分有问题:self.taggings.tag.id,但我不太确定如何修复它。
有什么建议吗?
模型:
**post.rb:**
has_many :taggings, dependent: :destroy
has_many :tags, through: :taggings
**tag.rb:**
has_many :taggings, :dependent => :destroy
has_many :posts, :through => :taggings
**tagging:**
attr_accessible :tag_id, :post_id
belongs_to :post
belongs_to :tag编辑
post.rb:
before_save :publish_post
protected
def publish_post
if self.status == "Published" && self.published_at.nil?
self.published_at = Time.now
end
endtagging.rb:
private
def increment_tag_counter_cache
if self.post.status == "Published" && self.post.published_at.nil?
Tag.increment_counter(:posts_count, self.tag.id)
end
end发布于 2012-12-28 12:10:06
这个例子有点误导..。
您必须将回调和计数代码放置到标记模型中:
private
after_create :increment_tag_counter_cache
after_destroy :decrement_tag_counter_cache
def increment_tag_counter_cache
Tag.increment_counter(:posts_count, self.tag.id) #
end
def decrement_tag_counter_cache
Tag.decrement_counter(:posts_count, self.tag.id)
end您可以将其留在Post中,但在这种情况下,您必须为所有分配的标记增加计数器。当post模型已经知道它的标记(取决于应用程序逻辑)时,必须执行此代码:
def increment_tag_counter_cache
tags.each do |tag| # if .tags contain Tag objects... or has_many :tags, :through => :tagggings
Tag.increment_counter(:posts_count, tag.id)
end
end但把这段代码放在后面的坏主意里。更新帖子时,你会做些什么?根据代码,它将再次增加计数器。当您添加新标记或移除时,您将做什么:您必须为每一种情况编写特殊的代码。真没意思。
发布于 2012-12-28 15:27:58
HOWTO只为具有:=“已发布”的帖子增加计数器
职位模式:
after_save :increment_tag_counters # covers :save, :create, :update methods
before_destroy :correct_tag_counters
def published?
self.status == "Published"
end
def increment_tag_counters? # if changes provided and previous status wasn't "published"
status_changed? && changed_attributes["status"] != "Published"
end
def decrement_tag_counters? # if changes provides and previous status was "published"
status_changed? && changed_attributes["status"] == "Published"
end
def increment_tag_counters
if published? && increment_tag_counters?
taggings.each {|tagging| tagging.increment_tag_counter_cache}
elsif decrement_tag_counters?
taggings.each {|tagging| tagging.decrement_tag_counter_cache}
end
end
def correct_tag_counters
if published?
taggings.each {|tagging| tagging.decrement_tag_counter_cache}
end
end标签模型:
after_create :increment_tag_counter_cache
after_destroy :decrement_tag_counter_cache
def increment_tag_counter_cache
Tag.increment_counter(:posts_count, self.tag.id) if post.published?
end
def decrement_tag_counter_cache
Tag.decrement_counter(:posts_count, self.tag.id) if !post.published? || post.decrement_tag_counters?
endhttps://stackoverflow.com/questions/14068354
复制相似问题