#ruby-on-rails #rails-activerecord
Вопрос:
При попытке удалить a User
в приложении Rails 6 я получаю следующую ошибку:
irb(main)> u = User.last
=> #<User id: 43, email: [FILTERED], ...>
irb(main)> u.destroy
(0.0ms) SELECT sqlite_version(*)
TRANSACTION (0.0ms) begin transaction
Folder Destroy (0.7ms) DELETE FROM "folders" WHERE "folders"."id" = ? [["id", 43]]
TRANSACTION (0.1ms) rollback transaction
/sqlite3/statement.rb:108:in `step': SQLite3::ConstraintException: FOREIGN KEY constraint failed (ActiveRecord::InvalidForeignKey)
/sqlite3/statement.rb:108:in `step': FOREIGN KEY constraint failed (SQLite3::ConstraintException)
Большинство решений, которые у меня есть для этого, заключались в использовании dependent: :destroy
и. after_destroy
Как вы можете видеть в моей User
модели, я уже использую оба:
class User < ApplicationRecord
has_many :folders, dependent: :destroy
has_many :articles, through: :folders
after_destroy :destroy_articles
private
def destroy_articles
self.articles.destroy_all
end
end
Как удалить папки и статьи Пользователя при удалении Пользователя?
Обновление на основе комментариев:
# /app/models/folder.rb
class Folder < ApplicationRecord
belongs_to :user
has_many :articles
validates :name, presence: true, uniqueness: { scope: :user_id }
end
# /app/models/article.rb
class Article < ApplicationRecord
belongs_to :user
belongs_to :folder
validates :title, presence: true
validates :link, presence: true, uniqueness: { scope: :user_id }
end
Решение:
Проблема заключалась в том, что статьи нужно было уничтожить до появления папок. Изменив Folder
модель, как показано ниже, я смог сделать это без ошибок.
# /app/models/folder.rb
class Folder < ApplicationRecord
before_destroy :destroy_articles
belongs_to :user
has_many :articles
private
def destroy_articles
self.articles.destroy_all
end
end
Комментарии:
1. Не уверен в точной проблеме, но есть ли
Folder
user_id
колонка? Запрос на удаление папок гласит:DELETE FROM "folders" WHERE "folders"."id" = ? [["id", 43]]
где он должен быть указанDELETE FROM "folders" WHERE "folders"."user_id" = ? [["user_id", 43]]
2.
Folders
иArticles
у обоих естьuser_id
колонки.3. Я согласен с @Deepesh в этом вопросе, запрос выглядит подозрительно. Как выглядит
Folder
модель?4. Я обновил вопрос, чтобы включить модель папок.
5. Не должно
dependent: :destroy
ли это быть в модели папокhas_many :articles
, а не в модели пользователя? Я подозреваю, что это заставляет его пытаться удалить статью, используя идентификатор пользователя, которого, конечно, нет.