Я действительно застрял на этом ... , я думаю, что исправил это, но я хотел бы быть уверен. Пример был упрощен.
Что я хочу
Я бы хотел, чтобы Трек входил в 1 или более Альбомы и имел бы возможность удалять уничтожать записи:
class Track < ApplicationRecord
has_many :album_tracks, dependent: :destroy
has_many :albums, through: :album_tracks, dependent: :destroy
end
class AlbumTrack < ApplicationRecord
belongs_to :album
belongs_to :track
end
class Album < ApplicationRecord
has_many :album_tracks, dependent: :destroy
has_many :tracks, through: :album_tracks, dependent: :destroy
end
Это позволяет мне получить все дорожки альбома (Album.last.tracks
) и все альбомы, в которых есть дорожка (Track.last.albums
)
Однако, когда я пытаюсь удалить объект (Album.last.delete
или Track.last.delete
), я сталкиваюсь с этой ошибкой (для Альбом ):
ActiveRecord::InvalidForeignKey: PG::ForeignKeyViolation: ERROR: update or delete on table "albums" violates foreign key constraint "fk_rails_4ab23890cf" on table "album_tracks"
DETAIL: Key (id)=(3) is still referenced from table "album_tracks".
Я понимаю, что я оставляю запись о сиротах в "album_track"
(но я, хотя и предотвратил это, используя dependent: :destroy
)
Решение?
Отсюда: Разница между уничтожением и удалением
Чтобы применить обратные вызовы объекта before_destroy и after_destroy или любые: зависимые параметры ассоциации, используйте # destroy.
https://api.rubyonrails.org/classes/ActiveRecord/Persistence.html#method-i-delete
Вот так я чистил свою БД:
print 'Cleaning DB...'
[..., Track, Album, ...].each(&:delete_all)
puts "\u2713"
=> Я заменил delete_all
на destroy_all
и теперь у меня больше нет ошибок при запуске моего seed.rb
.
Я могу запустить Track.last.destroy
, Album.destroy_all
или даже Album.last.tracks.first.destroy
.
Все хорошо или я что-то упустил? Есть ли что-нибудь, что я мог бы улучшить?
Спасибо за ваше время