2012-03-28 6 views
5

各タグの投稿の数を「カウンタキャッシュ」しようとしています。アフターセーブコールバックは機能していますが、after destroyは動作していません。破壊SQLのように見えるが正しくありません。ActiveRecord - has_many:through、:dependent =>:destroy 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

table_name =の代わりにset_table_nameを使用してみてください。私は、メソッドset_table_nameがもう少し変わると思います。 –

+0

@joe Pymそれは動作しませんでした。さらに、set_table_nameは廃止予定です。 - > DEPRECATION警告:set_table_nameの呼び出しは非推奨です。代わりに 'self.table_name = 'the_name''を使用してください。 – Marcelo

+1

私の状況で非常に似たエラーが発生しています。私も答えが欲しいです。 – user1149547

答えて

0

でなければなりません。これは適切に機能し、うまく動作し、タグの副作用を引き起こすことはなく、競合状態でカウントを失わないはずです。

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)に追加することでした。

:dependent => :destroyオプションを使用するには、レールに主キーが必要なようです。

+0

ありがとう、OPについて知りませんが、これは私のために働いていました。 ':dependent =>:destroy'の場合、Railsは期待通りに' WHERE foreign_key = smth'を実行せず、子をフェッチして、それぞれに対して 'WHERE id = smth'を実行します。 – yefrem

関連する問題