当通过 accepts_nested_attributes_for 为另一个对象完成时,如何修改关联对象的创建?

How do I modify the creation of an associated object when done via accepts_nested_attributes_for for another object?

我有一个 Job 型号,那个 belongs_to :company。两种型号 belong_to :user(即 current_user)。

Job accepts_nested_attributes_for :company.

我在 jobs/_form.html.erb 上有我的公司属性。

但是,发生的事情是,当创建公司对象时,它没有设置我想要的属性 (company.user_id)。

我不太确定如何强制它这样做。

这部分操作的日志如下所示:

Company Exists (1.4ms)  SELECT  1 AS one FROM "companies" WHERE ("companies"."id" IS NOT NULL) AND "companies"."slug" =  LIMIT   [["slug", "phish-me"], ["LIMIT", 1]]
  SQL (2.7ms)  INSERT INTO "companies" ("name", "logo", "description", "city", "state", "country", "email", "created_at", "updated_at", "slug") VALUES (, , , , , , , , , ) RETURNING "id"  [["name", "Acme Corp"], ["logo", "#<ActionDispatch::Http::UploadedFile:0x007f>"], ["description", "Some random description."], ["city", "Leesburg"], ["state", "Virginia"], ["country", "US"], ["email", "random@email.com"], ["created_at", 2016-06-24 09:50:49 UTC], ["updated_at", 2016-06-24 09:50:49 UTC], ["slug", "acme-corp"]]

我什至尝试在该表单的公司部分包含​​ user_id 的隐藏字段,但没有成功。

我在我的 Company#Create 操作中添加了一个 binding.pry 但它不起作用 - 所以它似乎没有被调用。

我不太确定如何修改创建事件并确保 company.user = job.user

我该怎么做?

编辑 1

我的Jobs#Create

  def create
    @job = current_user.jobs.new(job_params)

    respond_to do |format|
      if @job.save
        if @job.premium?
          @job.update_columns(price: 200.00)
        end
        format.html { redirect_to job_checkout_path(@job), notice: 'First step complete. Before listing is published, you need to make payment below.' }
        format.json { render :show, status: :created, location: @job }
      else
        format.html { render :new }
        format.json { render json: @job.errors, status: :unprocessable_entity }
      end
    end

这里没什么特别的。

这是我的 jobs/_form.html.erb:

<%= simple_form_for(@job) do |f| %>
  <%= f.error_notification %>

  <div class="form-group">
    <%= f.input_field :title %>
  </div>

    # truncated for brevity    

  <div class="form-group">
    <%= f.association :company, collection: [['New Company', nil]] + current_user.companies.pluck(:name, :id), include_blank: 'Please Select Company', input_html: { id: 'company-select' } %>
  </div>

  <fieldset id='job-fields'>
      <%= f.simple_fields_for :company, @job.build_company do |ff| %>
        <%= ff.input :user_id, as: :hidden %>
      <div class="form-group">
        <%= ff.input_field :name, class: "form-control", placeholder: "Company Name" %>
      </div>
      <div class="form-group">
        <%= ff.input_field :logo, as: :file, placeholder: "Upload company logo." %>
      </div>
      <div class="form-group">
        <%= ff.input_field :description, as: :text, class: "form-control", placeholder: "Enter a brief description of the company." %>
      </div>
      <div class="form-group">
        <%= ff.input_field :city, class: "form-control", placeholder: "Enter the city (E.g. San Francisco, Cleveland)" %>
      </div>
      <div class="form-group">
        <%= ff.input_field :state, class: "form-control", placeholder: "Enter the state (E.g. California, Ohio)" %>
      </div>
      <div class="form-group">
        <%= ff.input_field :email, class: "form-control", placeholder: "Contact Email Address for the company. This won't be published publicly." %>
      </div>
      <div class="form-group">
        <%= ff.input :country, class: "form-control" %>
      </div>
      <% end %>
  </fieldset>

  <div>
    <%= link_to "Cancel", root_path, class: "btn btn-lg btn-outline btn-danger pull-left" %></p>
    <%= f.button :submit, class: "btn btn-lg btn-primary pull-right" %>
  </div>

<% end %>

您可以考虑使用合并添加 user_id,这会有些棘手,具体取决于嵌套属性和强参数的设置方式,但在创建操作中,类似(您需要检查实际的 post 参数,这只是示例):

 job_params["company_attributes"].merge!("user_id" => current_user.id)

您也可以尝试在您的私有强参数方法中合并以设置 job_params...

但最简单的方法是,如果 Job 得到正确设置 user_id,然后在你的 Job 模型中,创建一个回调来设置 user_id

 # app/models/job.rb

 after_create :set_company_user_id

 def set_company_user_id
   self.company.update_column(:user_id, self.user_id)
 end

这是假设您的公司模型 has_many :jobs,否则如果不是,则在公司模型中执行此操作可能更有意义。如果您对一家公司有多个职位,那么将此切换为使公司接受职位的嵌套属性会更合乎逻辑,因为公司可以有多个职位。