2013-06-05 2 views
12
class Post < ActiveRecord::Base 
    has_many :posts_tags 
    has_many :tags, through: :posts_tags 
end 

class PostsTag < ActiveRecord::Base 
    belongs_to :post 
    belongs_to :tag 
end 

class Tag < ActiveRecord::Base 
    has_many :posts_tags 
    has_many :posts, through: :posts_tags 
end 

Когда сообщение уничтожено, я хочу, чтобы все его ассоциации также были удалены. Я НЕ хочу, чтобы проверки на модели PostsTag выполнялись. Я просто хочу удалить.Правильный способ удаления has_many: через записи объединений?

Я обнаружил, что добавление зависимости от отношения к тегам сообщений из модели Post работает, как я хочу: has_many :posts_tags, dependent: :delete_all.

Однако документация по этому вопросу, по-видимому, предполагает, что я должен сделать это вместо этого: has_many :tags, through: :posts_tags, dependent: :delete_all. Когда я это делаю, объект Tag уничтожается и объект соединения остается.

http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html#method-i-has_many

Для has_many, уничтожить всегда будет вызывать метод уничтожения из записи (ей) быть удалены, так что обратные вызовы выполняются. Однако удаление будет либо выполнять удаление в соответствии со стратегией, заданной опцией: зависимый, либо если нет: зависимая опция указана, то она будет следовать стратегии по умолчанию. Стратегия по умолчанию: nullify (установить внешние ключи в nil), за исключением has_many: through, где по умолчанию используется команда delete_all (удалить записи объединения, не выполняя обратные вызовы).

  1. Как я могу иметь стратегию по умолчанию на самом деле использовали? Если я уйду: полностью зависеть, записи вообще не удаляются. И я не могу просто указать: зависит от отношения has_many. Rails возвращается и говорит: «Зависимая опция ожидает либо: destroy,: delete_all,: nullify или: restrict ({})».
  2. Если я не указываю: зависит от любого из отношений, это не отменяет post_id на объекте PostsTag, как это, кажется, предполагает

Возможно, я читала это не так, и подход, который я нашел работы - правильный путь?

+1

Что произойдет, если тег используется несколькими сообщениями? Если одно сообщение удалено, другие сообщения будут затронуты. –

+0

true, а тег должен иметь 'has_many: posts, через:: posts_tags' не сообщения, я бы использовал' has_many: posts_tags, depend:: destroy', чтобы удалить posts_tag и оставить теги в одиночку. Вы можете удалить осиротевшие теги с помощью задачи или консоли. – rmagnum2002

+0

Исправлена ​​связь, спасибо. Я просто пытаюсь понять документацию.Формулировка путается – Brian

ответ

17

Ваша оригинальная идея:

has_many :posts_tags, dependent: :delete_all 

это именно то, что вы хотите. Вы делаете не хотите объявить это на ассоциации has-many-but :tags, поскольку это уничтожит все связанные теги. То, что вы хотите удалить, - это сама ассоциация - вот что представляет собой модель объединения PostTag.

Так почему же документы говорят, что они делают? Вы недопонимание сценарий, что документация с описанием:

Post.find(1).destroy 
Post.find(1).tags.delete 

Первый вызов (ваш сценарий) будет просто уничтожить пост. То есть, если вы не укажете стратегию :dependent, как я предлагаю вам. Второй вызов - это то, что описывает документация. Вызов .tags.delete не будет (по умолчанию) фактически уничтожить теги (поскольку к ним присоединяется has-many-through), но связанная модель соединения, которая объединяет эти теги.

+0

ahh спасибо, что имеет смысл – Brian

Смежные вопросы