【问题标题】:Rails - Create an object in database from nested params attributesRails - 从嵌套的参数属性在数据库中创建一个对象
【发布时间】:2017-01-12 08:03:09
【问题描述】:

我有一个 Rails 应用程序,用户在其中创建了一个新工作,并且在 job/new _form 上,我让用户输入工作所属公司的信息。

数据库中的工作只是它的创建日期、创建它的用户,以及公司、联系人、工作站点等表的附加外键。

我的申请中的公司has_many 工作和工作belongs_to 公司。

所以,在我将 Job 持久化到数据库之前,我必须先保存新的 Company,然后我才能获取它的主键并将其放入 Jobs company_id 外键元组中。

我在 params 哈希中正确返回了所有内容,如下所示:

>> params
=> {"utf8"=>"✓", "authenticity_token"=>"NiQO7Wlq87h3+YM//yIEMnctVKectfmZBb74suFOCcmg7g4YyCmGo2OiciOd3VuRDR52tKoE0v9nq1LYoTqHOQ==", "job"=>{"date"=>"2016-09-04 16:06:49 -0700", "user_id"=>"1", "company_id"=>"", "subcontractor_id"=>"", "jobsite_id"=>"", "companies"=>{"name"=>"Test Company", "phone"=>"(530)111-2222", "street"=>"3177 testing st", "city"=>"cameron park", "state"=>"ca", "zip"=>"95682", "email"=>"testemail@mail.com", "website"=>"testcompany.com"}}, "commit"=>"Create Job", "controller"=>"jobs", "action"=>"create"}
>>

我可以通过params[:job][:companies]访问公司信息

所以我的理论是,在 Jobs 控制器中,在 def create 中,在调用 @job.save 之前,我必须先执行 @company.new(company_params)@company.save 以便我可以保存公司,然后获取其主键从数据库。

但是我需要一点帮助。

有没有人可以给点建议?

编辑:

这是我的_form中的一个示例,

  <%= f.fields_for @company do |company| %>
    <div class="field">
      <%= company.label :name %>
      <%= company.text_field :name %>
    </div>

在我拥有的作业控制器中,

  def new
    @job = Job.new
    @company = Company.new
  end

  def create
    @job = Job.new(job_params)
    @company = Company.new(params[:job][:company])

Job.rb 有

accepts_nested_attributes_for :company

参数是:

def job_params
  params.require(:job).permit(:date, :user_id, :company_id, :subcontractor_id, :jobsite_id, :company_attributes => [:name, :phone, :street, :city, :state, :zip, :email, :website])  
end

当我提交表单时,属性返回为company 而不是company_attributes,所以它告诉我“Unpermitted parameter: company”。

我设置它的方式,@job 没有功能来做@job.company.build,它们不是这样嵌套的。公司就是一张桌子,一个公司可以有很多工作,一个工作能做的就是执行@job.company

这就是为什么我需要先创建公司,这样我才能得到它的主键,然后说@job.company_id = @company.id

我希望这能让事情更清楚。

【问题讨论】:

    标签: ruby-on-rails model-view-controller nested-attributes params


    【解决方案1】:

    您可以使用nested_attributes_for :companycompanies,查看您的代码并看到company_id,我假设它是company

    =>{
      ...
      "job"=>{
        "date"=>"2016-09-04 16:06:49 -0700",
        "user_id"=>"1", # <= Really shouldn't do this...
        "company_attributes"=>{
          "name"=>"Test Company",
          "phone"=>"(530)111-2222",
          "street"=>"3177 testing st",
          "city"=>"cameron park",
          "state"=>"ca", "zip"=>"95682",
          "email"=>"testemail@mail.com",
          "website"=>"testcompany.com"
        }
      }, 
      ...
    }
    

    然后在您允许的参数中,您可以执行以下操作:

    def job_params
      params.require(:job).permit(:date, :company_id, :subcontractor_id, :company_attributes => [:name, :phone, :street, :city, :state, :email, :website])
    end
    

    然后您可以在您的form_tag 中使用fields_for :company。此外,在新的工作操作中添加一个空白公司。

    def new
      @job = Job.new
      @job.build_company
    end
    

    编辑

    你不能像这样在feilds_for上使用@company

    也许是fields_for :company, @company,但不仅仅是@company

    <%= f.fields_for :company do |company| %>
    

    您必须使用符号来表示记录的名称。

    否则字段名称将是 "job[company]" 或在您的情况下为 "job[companies]" 而不是 "job[company_attributes]"

    无论哪种方式,您都可以将新对象添加到新作业的关联中,而不是添加实例变量。

    @job.build_company
    

    你可以通过这个工作仓库自己尝试一下:https://www.github.com/frank184/surveysays

    供参考: http://apidock.com/rails/ActionView/Helpers/FormHelper/fields_for

    【讨论】:

    • 我在 form_tag 中使用了 fields_for,但是,如果我使用“fields_for :companies”,它只会呈现字段。在其他任何地方我都在使用“nested_attributes_for:company”和“.permit(...,company_attributes [...])”所以在作业控制器中它对我大喊“未经允许的参数:公司”,我不知道如何解决这个问题,这似乎来自 form_tag
    • @CodyPritchard 发布您的表单、您的控制器操作和允许的参数。您的问题是在您的参数中发送"companies":{...} 而不是"company_attributes":{...}。未呈现字段的原因是因为您需要向新公司发送新工作(即@job.company.build)。
    • @CodyPritchard 更新了我的帖子
    猜你喜欢
    • 2014-04-29
    • 2020-12-21
    • 1970-01-01
    • 1970-01-01
    • 2018-07-16
    • 2021-06-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多