rails-dependent::destroy使用错误的ID值



my schema.db

create_table 'pet', force: :cascade do |t|
t.string 'name'
t.datetime 'created_at', precision: 6, null: false
t.datetime 'updated_at', precision: 6, null: false
end
create_table 'user', force: :cascade do |t|
t.string 'name'
t.references :pet, index: true, foreign_key: { on_delete: :nullify }
t.datetime 'created_at', precision: 6, null: false
t.datetime 'updated_at', precision: 6, null: false
end

用户模型

class User < ApplicationRecord
has_one :pet, foreign_key: :id, dependent: :destroy
end

宠物模型

class Pet < ApplicationRecord
belongs_to :user, optional: true
end

show.erb

<%= link_to t('delete'), user_path(id: @user.id), method: :delete %>
<%= link_to t('.pet_delete'), pet_path(@auser.pet_id), method: :delete %>

用户控制器

def destroy
User.destroy(params[:id])
redirect_to users_path
end

宠物控制器

def destroy
Pet.destroy(params[:id])
redirect_to users_path
end

问题:如果我用宠物id 5删除用户id 5,依赖销毁工作良好,它删除(用户id 5(&(宠物id 5(

如果我有宠物id为nil的用户id 5,以及用户id 4与宠物id 5,当我删除用户id 5时,用户5与用户4的宠物(宠物id 5(一起删除所以剩余结果->用户id 5删除,用户id 4没有宠物

有点不对劲,但我找不到问题出在哪里。dependent destroy在同一时间只能找到相同的userId和petId。

我希望如果我删除带有宠物id 1的用户id 3,希望删除良好我尝试改变依赖销毁的位置(在宠物模型上(,将schema.rb的on_delete nullify更改为delete,但不起作用。

问题是您将id指定为外键。

class User < ApplicationRecord
has_one :pet, foreign_key: :id, dependent: :destroy
end

您需要改为指定user_id

class User < ApplicationRecord
has_one :pet, foreign_key: :user_id, dependent: :destroy
end

但是,在这种简单的情况下,您根本不需要指定外键。只要在pets表中有一个名为user_id的列,它就会正常工作,因为Rails会自动假设外键应该是<model>_id

此外,请记住,外键应添加到,而不是。因此,您需要将user_id添加到pets表中,而不是将pet_id添加到users表中。

最后,你的schema.rb应该是这样的:

create_table 'pet', force: :cascade do |t|
t.string 'name'
t.datetime 'created_at', precision: 6, null: false
t.datetime 'updated_at', precision: 6, null: false
t.references :user, index: true, foreign_key: { on_delete: :nullify } # <== this should be added
end
create_table 'user', force: :cascade do |t|
t.string 'name'
# t.references :pet, index: true, foreign_key: { on_delete: :nullify } <== this should be removed
t.datetime 'created_at', precision: 6, null: false
t.datetime 'updated_at', precision: 6, null: false
end

相关内容

  • 没有找到相关文章

最新更新