ActiveRecord - has_many: through, зависимый =>: уничтожить sql не правильно - PullRequest
5 голосов
/ 28 марта 2012

Я пытаюсь «противостоять кешу» количества постов в каждом теге. Обратный вызов после сохранения работает, а удаление после - нет. Похоже, уничтожить 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}

Ответы [ 3 ]

1 голос
/ 07 июля 2015

У меня была точно такая же проблема, исправление для меня заключалось в добавлении столбца первичного ключа в таблицу соединений (PostTag в вашем случае).

Похоже, что rails нужен первичный ключ для :dependent => :destroy возможность работать.

0 голосов
/ 12 ноября 2014

Может быть потому, что в моделях, которые вы использовали

#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

0 голосов
/ 19 октября 2014

Я бы предложил отдельные функции увеличения / уменьшения и не использовать count + save. Это должно работать правильно, работать хорошо, не вызывать побочных эффектов на Tag и не портить счет в условиях гонки.

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...