Rails 4 中的奇怪 has_many 关联行为

Strange has_many Association Behavior in Rails 4

我有两个 table,UserAllergy。它们通过另一个 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: []}, ____, ____)