Rails 4 中的奇怪 has_many 关联行为
Strange has_many Association Behavior in Rails 4
我有两个 table,User
和 Allergy
。它们通过另一个 table、UserAllergy
连接。这些模型符合预期:
class User
has_many :user_allergies
has_many :allergies, through: :user_allergies
end
class UserAllergy
belongs_to :user
belongs_to :allergy
end
class Allergy
has_many :user_allergies
has_many :users, through :user_allergies
end
令我感到困惑的是,在我的 User
表单中,从多值 collection_select
创建过敏。
我有以下字段:
<%= f.collection_select :allergy_ids,
Allergy.all,
:id,
:name,
{},
{ class: 'form-control', multiple: true }
%>
如果我选择了 ID 为 1 和 2 的 Allergies
,这会正确地将密钥插入到我的参数中:
{ user: { id: "1", allergy_ids: ["", "1", "2"] } }
当我创建用 @user = User.new( my_params )
实例化的用户时,出现了奇怪的行为。 Rails 不是将提供的 allergy_ids
插入连接 table,而是执行查询以获取用户的所有当前 user_allergies
,然后删除所有当前 user_allergies
:
Started PATCH "/employees/regular_user" for 127.0.0.1 at 2015-06-18 22:08:30 -0400
Processing by UsersController#update as HTML
Parameters: {"utf8"=>"✓", "user"=>{ "allergy_ids"=>["", "1", "2", "3"]}, "button"=>"", "id"=>"regular_user"}
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 2]]
(0.1ms) begin transaction
Allergy Load (0.1ms) SELECT "allergies".* FROM "allergies" INNER JOIN "user_allergies" ON "allergies"."id" = "user_allergies"."allergy_id" WHERE "user_allergies"."user_id" = ? [["user_id", 1]]
SQL (0.1ms) DELETE FROM "user_allergies" WHERE "user_allergies"."user_id" = ? AND "user_allergies"."allergy_id" = 1 [["user_id", 1]]
(27.4ms) commit transaction
Redirected to http://localhost:3000/employees/regular_user
Completed 302 Found in 32ms (ActiveRecord: 27.8ms)
有谁知道是什么原因造成的,或者我需要做什么才能隐含地产生过敏反应?我试过 accepts_nested_attributes_for
并改变了形式以使用 fields_for
.
您遗漏了难题的一部分,即过敏与用户之间的关系。
class Allergy
has_many :user_allergies
has_many :users, through: :user_allergies
end
所以,我去查看了我的具有类似功能的代码。这是我的创建方法的样子。这是在学校环境中创建一个分配给学生组的学生(我没有使用 "class" 因为 Ruby 不喜欢那样)。
def create
@student = Student.new(student_params)
if @student.save
@student.student_groups = StudentGroup.where(id: params[:student][:student_group_ids])
flash[:success] = "Student was successfully created."
redirect_to @student
else
render 'new', notice: "Your student could not be created."
end
end
我在创建 student_params 时完全忽略了学生组 ID,因为我没有将它们用于批量分配。
是的,多了一行代码。我真的很想知道是否有办法通过批量分配来完成此任务。
试试下面的代码-
params.require(:user).permit(___, ____, {allergy_ids: []}, ____, ____)
我有两个 table,User
和 Allergy
。它们通过另一个 table、UserAllergy
连接。这些模型符合预期:
class User
has_many :user_allergies
has_many :allergies, through: :user_allergies
end
class UserAllergy
belongs_to :user
belongs_to :allergy
end
class Allergy
has_many :user_allergies
has_many :users, through :user_allergies
end
令我感到困惑的是,在我的 User
表单中,从多值 collection_select
创建过敏。
我有以下字段:
<%= f.collection_select :allergy_ids,
Allergy.all,
:id,
:name,
{},
{ class: 'form-control', multiple: true }
%>
如果我选择了 ID 为 1 和 2 的 Allergies
,这会正确地将密钥插入到我的参数中:
{ user: { id: "1", allergy_ids: ["", "1", "2"] } }
当我创建用 @user = User.new( my_params )
实例化的用户时,出现了奇怪的行为。 Rails 不是将提供的 allergy_ids
插入连接 table,而是执行查询以获取用户的所有当前 user_allergies
,然后删除所有当前 user_allergies
:
Started PATCH "/employees/regular_user" for 127.0.0.1 at 2015-06-18 22:08:30 -0400
Processing by UsersController#update as HTML
Parameters: {"utf8"=>"✓", "user"=>{ "allergy_ids"=>["", "1", "2", "3"]}, "button"=>"", "id"=>"regular_user"}
CACHE (0.0ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT 1 [["id", 2]]
(0.1ms) begin transaction
Allergy Load (0.1ms) SELECT "allergies".* FROM "allergies" INNER JOIN "user_allergies" ON "allergies"."id" = "user_allergies"."allergy_id" WHERE "user_allergies"."user_id" = ? [["user_id", 1]]
SQL (0.1ms) DELETE FROM "user_allergies" WHERE "user_allergies"."user_id" = ? AND "user_allergies"."allergy_id" = 1 [["user_id", 1]]
(27.4ms) commit transaction
Redirected to http://localhost:3000/employees/regular_user
Completed 302 Found in 32ms (ActiveRecord: 27.8ms)
有谁知道是什么原因造成的,或者我需要做什么才能隐含地产生过敏反应?我试过 accepts_nested_attributes_for
并改变了形式以使用 fields_for
.
您遗漏了难题的一部分,即过敏与用户之间的关系。
class Allergy
has_many :user_allergies
has_many :users, through: :user_allergies
end
所以,我去查看了我的具有类似功能的代码。这是我的创建方法的样子。这是在学校环境中创建一个分配给学生组的学生(我没有使用 "class" 因为 Ruby 不喜欢那样)。
def create
@student = Student.new(student_params)
if @student.save
@student.student_groups = StudentGroup.where(id: params[:student][:student_group_ids])
flash[:success] = "Student was successfully created."
redirect_to @student
else
render 'new', notice: "Your student could not be created."
end
end
我在创建 student_params 时完全忽略了学生组 ID,因为我没有将它们用于批量分配。
是的,多了一行代码。我真的很想知道是否有办法通过批量分配来完成此任务。
试试下面的代码-
params.require(:user).permit(___, ____, {allergy_ids: []}, ____, ____)