2012-03-28 58 views
5

我想“计数器缓存”每个标签中的帖子数。后保存回调工作,但后破坏不是。看起来像销毁sql是不正确的。ActiveRecord - has_many:通过,:依赖=>:销毁sql是不正确的

class Post < ActiveRecord::Base 
    has_many :post_tags, :dependent => :destroy 
    has_many :tags, :through => :post_tags 
end 

class Tag < ActiveRecord::Base 
    has_many :post_tags, :dependent => :destroy 
    has_many :posts, :through => :post_tags 
end 

class PostTag < ActiveRecord::Base 
    self.table_name = :posts_tags 
    belongs_to :post 
    belongs_to :tag 

    after_save :update_tag_posts_count 
    after_destroy :update_tag_posts_count 

    def update_tag_posts_count 
    tag.posts_count = tag.posts.count 
    tag.save 
    end 
end 

测试失败

# @tag.posts_count == 10 
Failure/Error: @tag.posts.first.destroy 
ActiveRecord::StatementInvalid: 
Mysql2::Error: Unknown column 'posts_tags.' in 'where clause': DELETE FROM `posts_tags` WHERE `posts_tags`.`` = NULL 

正确的SQL应该是

DELETE FROM `posts_tags` WHERE `posts_tags`.`post_id` = {the post id} 
+0

尝试使用set_table_name而不是table_name =?我认为set_table_name方法改变了一些东西。 – 2012-03-28 15:58:28

+0

@joe Pym这没有奏效。此外,set_table_name现在已被弃用。 - > DEPRECATION警告:不建议调用set_table_name。请改用'self.table_name ='the_name''。 – Marcelo 2012-03-29 15:03:59

+1

我在我的情况中遇到了非常类似的错误。我也想要一个答案。 – user1149547 2012-07-18 00:08:15

回答

0

我建议单独递增/递减功能,而不是使用count +保存。这应该正常运行,表现良好,不会在标签上引发副作用,并且不会在竞赛条件中混淆您的计数。

class PostTag < ActiveRecord::Base 

    belongs_to :post 
    belongs_to :tag 

    after_create :increment_tag_posts_counter 
    after_destroy :decrement_tag_posts_counter 

    private 

    def increment_tag_posts_counter 
    Tag.increment_counter :posts_count, post_id 
    end 

    def decrement_tag_posts_counter 
    Tag.decrement_counter :posts_count, post_id 
    end 
end 
0

可能是因为你的模型使用的

#post.rb 
has_many :post_tags, :dependent => :destroy 
#tag.rb 
has_many :post_tags, :dependent => :destroy 

代替

#post.rb 
has_many :posts_tags, :dependent => :destroy 
#tag.rb 
has_many :posts_tags, :dependent => :destroy 

1

我有完全相同的问题,我的修补程序是将主键列添加到连接表(PostTag在您的情况)。

看来,rails需要主键来使:dependent => :destroy选项正常工作。

+0

谢谢,不知道OP,但这对我有用。对于':dependent =>:destroy',Rails不会运行'WHERE foreign_key = smth',因为它可以获取孩子,然后为每个孩子运行'WHERE id = smth'。 – yefrem 2017-01-23 12:48:31

相关问题