Как правильно указать уничтожение объектов для has_many: via association? - PullRequest
0 голосов
/ 10 января 2020

Я всегда писал подобный код:

class Post < ApplicationRecord
  has_many :posts_and_images
  has_many :images,
           through: :posts_and_images,
           dependent: :destroy do
             def <<(image)
               super(Array(image) - proxy_association.owner.images)
             end
           end
end

class PostsAndImage < ApplicationRecord
  belongs_to :post
  belongs_to :image
end

class Image < ApplicationRecord
  has_many :posts_and_images
  has_many :posts,
           through: :posts_and_images,
           dependent: :destroy
end

Я использую код с proxy_association по мере необходимости. Я думаю, что в этом случае это не важно. Я просто показываю это так, чтобы была полная картина.

Теперь я решил еще раз изучить документацию и различные примеры, которые разные люди демонстрировали в своих блогах.

Итак, я нашел похожая опция (на основе моего предыдущего кода):

class Post < ApplicationRecord
  has_many :posts_and_images,
           dependent: :destroy

  has_many :images,
           through: :posts_and_images do
             def <<(image)
               super(Array(image) - proxy_association.owner.images)
             end
           end
end

class PostsAndImage < ApplicationRecord
  belongs_to :post
  belongs_to :image
end

class Image < ApplicationRecord
  has_many :posts_and_images,
           dependent: :destroy

  has_many :posts,
           through: :posts_and_images
end

В обоих примерах я запускал похожий сценарий, когда удалял пост или изображение. И, видимо, оба, когда они работают одинаково. По крайней мере, на первый взгляд, это так.

Не могли бы вы объяснить мне нюансы обоих примеров? Какой из них наиболее предпочтителен? Каковы плюсы и минусы каждого из них?

1 Ответ

0 голосов
/ 10 января 2020

Прикрепление dependent destroy к какой строке имеет значение:

В первом случае (хотя и странно):

  • Уничтожение сообщения будет выполнено, но "его" изображения сначала будет уничтожен автоматически.
  • Будет выполнено уничтожение изображения, но "его" сообщения будут уничтожены первыми автоматически.

Во втором случае:

  • Уничтожение поста или изображения уничтожит их post_and_image, т. Е. Модель, которая создавала связь между ними и самим изображением или постом through, не будет затронута.

Я вижу огромную разницу. Ты видишь это? Попробуйте в консоли rails.

Пример:

Post_A has 2 изображения: Image_A и Image_B

Post_B has 2 одинаковых изображения, т.е. Image_A и Image_B.

Теперь попробуйте оба варианта выше, и результаты будут интересны.

...