首页 > 解决方案 > Rails 不创建关联模型

问题描述

我创建了一个表单,用户可以在其中创建个人资料。在表格中,用户可以选择多个公司。配置文件通过名为 profile_companies 的连接表包含许多公司。我的代码确实创建了一个新的配置文件,但它没有创建关联。这意味着当我在控制台中点击时: Profile.last.companies 它返回一个空数组。当我在创建配置文件之前检查参数时,它确实向我显示了 company_ids 的完整数组。所以看起来它无法传递这些值并创建关联。有谁知道错误在哪里?

这是我的个人资料模型:

class Profile < ApplicationRecord
  belongs_to :user
  has_many :profile_companies
  has_many :companies, through: :profile_companies

  STATUSES = ["currently looking for a job", "employed but open for a new challenge"]
  validates :status, inclusion: {in: STATUSES}
end

这是我的公司模型:

class Company < ApplicationRecord
  has_many :vacancies
  has_many :profile_companies
  has_many :profiles, through: :profile_companies
end

这是我的个人资料控制器:

class ProfilesController < ApplicationController
  def new
    @profile = Profile.new
  end
  def create
    @profile = Profile.new(params_profile)

    if @profile.save
      redirect_to profile_path
    else
      render :new
    end
  end

  private

  def params_profile
    params.require(:profile).permit(:status, :name, :content, :company_ids)
  end

end

这是我用来展示传递给控制器​​的参数的方法:

[1] pry(#<ProfilesController>)> params[:profile] => <ActionController::Parameters {"name"=>"test 4", "status"=>"employed but open for a new challenge", "company_ids"=>["", "31", "34"], "content"=>"test 4"} permitted: false>

这是我的日志:

Started POST "/profiles" for ::1 at 2019-08-05 22:54:36 +0200
Processing by ProfilesController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"bmmqCdtWvTcDjlbR6yGrdZTGj+t3O2NMwNKanY5qP84eCSsCuBVF4SdzDkQ+0YOe5q+CapWx5NLaftunZ+ANSg==", "profile"=>{"name"=>"test 4", "status"=>"employed but open for a new challenge", "company_ids"=>["", "17", "31", "32"], "content"=>"rrr"}, "commit"=>"Save your profile"}
  User Load (0.3ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["id", 16], ["LIMIT", 1]]
Unpermitted parameter: :company_ids
   (0.1ms)  BEGIN
   (0.1ms)  ROLLBACK
  Rendering profiles/new.html.erb within layouts/application
  Company Load (2.6ms)  SELECT "companies".* FROM "companies"
  CACHE Company Load (0.0ms)  SELECT "companies".* FROM "companies"
  CACHE Company Load (0.0ms)  SELECT "companies".* FROM "companies"
  Rendered profiles/new.html.erb within layouts/application (29.2ms)
  Rendered shared/_navbar.html.erb (1.4ms)
  Rendered shared/_flashes.html.erb (0.4ms)
Completed 200 OK in 178ms (Views: 170.6ms | ActiveRecord: 3.2ms)

标签: ruby-on-railsrubycheckbox

解决方案


有几件事。Unpermitted parameter: :company_ids首先,从消息中可以看出:

Started POST "/profiles" for ::1 at 2019-08-05 22:54:36 +0200
Processing by ProfilesController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"bmmqCdtWvTcDjlbR6yGrdZTGj+t3O2NMwNKanY5qP84eCSsCuBVF4SdzDkQ+0YOe5q+CapWx5NLaftunZ+ANSg==", "profile"=>{"name"=>"test 4", "status"=>"employed but open for a new challenge", "company_ids"=>["", "17", "31", "32"], "content"=>"rrr"}, "commit"=>"Save your profile"}
  User Load (0.3ms)  SELECT  "users".* FROM "users" WHERE "users"."id" = $1 ORDER BY "users"."id" ASC LIMIT $2  [["id", 16], ["LIMIT", 1]]
Unpermitted parameter: :company_ids
   (0.1ms)  BEGIN
   (0.1ms)  ROLLBACK
  Rendering profiles/new.html.erb within layouts/application
  Company Load (2.6ms)  SELECT "companies".* FROM "companies"
  CACHE Company Load (0.0ms)  SELECT "companies".* FROM "companies"
  CACHE Company Load (0.0ms)  SELECT "companies".* FROM "companies"
  Rendered profiles/new.html.erb within layouts/application (29.2ms)
  Rendered shared/_navbar.html.erb (1.4ms)
  Rendered shared/_flashes.html.erb (0.4ms)
Completed 200 OK in 178ms (Views: 170.6ms | ActiveRecord: 3.2ms)

...您使用permit不正确company_ids,因此不允许使用 。

它应该看起来更像:

def params_profile
  params.require(:profile).permit(:status, :name, :content, company_ids: [])
end

...因为company_ids是一个数组。允许的数组应该放在permit列表的末尾,有关更多信息,请参阅文档

其次,您的Profile模型没有company_ids属性。所以,当你这样做时,你可能会得到一个错误:

@profile = Profile.new(params_profile)

(TBH,我忘记了在这种情况下rails 有多聪明(或不聪明)。)这是你必须处理的另一件事。

第三,您的Profile模型包括belongs_to :user,但您从未分配用户,这就是您的交易获得ROLLBACK. 一般来说,要查看为什么会得到 a ROLLBACK,您可以执行以下操作:

if @profile.save!

...并且砰(!)将导致错误并提供解释。

要设置user_id,我建议您执行以下操作:

@profile = current_user.build_profile(params_profile)

这假设User has_one :profile. 有关更多信息,请参阅文档


推荐阅读