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