Rails 5 - 嵌套模型表单不保存子模型属性

时间:2017-10-03 18:09:15

标签: ruby-on-rails ruby nested-forms

我已经在这个问题上持续了几个星期了。

目前我有一个User模型,Employee模型和一个Employee_Contact模型。用户模型是使用Devise生成的。用户登录后,他们可以转到用户仪表板并使用嵌套表单创建员工。我遇到的问题是子模型Employee_Contact没有保存到数据库中。

架构:

  create_table "employee_contacts", force: :cascade do |t|
    t.string "street"
    t.string "city"
    t.string "state"
    t.string "zip"
    t.string "phone_num"
    t.string "alt_phone_num"
    t.string "email"
    t.string "emergency_contact_first_name"
    t.string "emergency_contact_last_name"
    t.string "emergency_contact_num"
    t.integer "user_id"
    t.integer "employee_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["employee_id"], name: "index_employee_contacts_on_employee_id"
    t.index ["user_id"], name: "index_employee_contacts_on_user_id"
  end

  create_table "employees", force: :cascade do |t|
    t.string "first_name"
    t.string "middle"
    t.string "last_name"
    t.string "sex"
    t.string "race"
    t.date "birthdate"
    t.integer "user_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.integer "employee_contact_id"
    t.index ["user_id"], name: "index_employees_on_user_id"
  end

  create_table "users", force: :cascade do |t|
    t.string "email", default: "", null: false
    t.string "encrypted_password", default: "", null: false
    t.string "reset_password_token"
    t.datetime "reset_password_sent_at"
    t.datetime "remember_created_at"
    t.integer "sign_in_count", default: 0, null: false
    t.datetime "current_sign_in_at"
    t.datetime "last_sign_in_at"
    t.inet "current_sign_in_ip"
    t.inet "last_sign_in_ip"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.index ["email"], name: "index_users_on_email", unique: true
    t.index ["reset_password_token"], name: 
    "index_users_on_reset_password_token", unique: true
    end
  end

这些是我的模特:

class User < ApplicationRecord
  devise :database_authenticatable, :registerable,
     :recoverable, :rememberable, :trackable, :validatable

  has_many :employees, :dependent => :destroy
end

class Employee < ApplicationRecord
  belongs_to :user
  has_one :employee_contact, inverse_of: :employee, autosave: true

  accepts_nested_attributes_for :employee_contact, allow_destroy: true
end

class EmployeeContact < Employee
  belongs_to :employee, inverse_of: :employee_contact
end

我的员工控制员:

class EmployeesController < ApplicationController
  before_action :authenticate_user!

  def index
    @employees = Employee.all
  end

  def new
    @employee = Employee.new
  end

  def create
    @employee = current_user.employees.create(employee_params)

    if @employee.save!
      redirect_to root_path
    else
      render :new, status: :unprocessable_entity
    end
 end

 private

 def employee_params
   params.require(:employee).permit(:first_name, :middle, :last_name, 
   :sex, :race, :birthdate, employee_contact: [:id, :street, :city, 
   :state, :zip, :phone_num, :email, :alt_phone_num, 
   :emergency_contact_first_name, :emergency_contact_last_name, 
   :emergency_contact_num])
   end
 end

我的观点表格:

      <%= form_with(model: @employee, local: true) do |form| %>
      <h3>Employee Profile Information</h3>

      <%= form.label :first_name %><br />
      <%= form.text_field :first_name %><br />

      <%= form.label :middle %><br />
      <%= form.text_field :middle %><br />

      <%= form.label :last_name %><br />
      <%= form.text_field :last_name %><br />

      <%= form.label :sex %><br />
      <%= form.text_field :sex %><br />

      <%= form.label :race %><br />
      <%= form.text_field :race %><br />

      <%= form.label :birthdate %><br />
      <%= form.date_field :birthdate %><br />

      <h3>Employee Contact Information</h3><br />

      <%= form.fields_for :employee_contacts do |builder| %>
        <%= builder.label :street %><br />
        <%= builder.text_area :street %><br />

        <%= builder.label :city %><br />
        <%= builder.text_area :city %><br />

        <%= builder.label :street %><br />
        <%= builder.text_area :street %><br />

        <%= builder.label :state %><br />
        <%= builder.text_area :state %><br />

        <%= builder.label :zip %><br />
        <%= builder.text_area :zip %><br />

        <%= builder.label :phone_num %><br />
        <%= builder.text_area :phone_num %><br />

        <%= builder.label :alt_phone_num %><br />
        <%= builder.text_area :alt_phone_num %><br />

        <%= builder.label :email %><br />
        <%= builder.text_area :email %><br />

        <%= builder.label :emergency_contact_first_name %><br />
        <%= builder.text_area :emergency_contact_first_name %><br />

        <%= builder.label :emergency_contact_last_name %><br />
        <%= builder.text_area :emergency_contact_last_name %><br />

        <%= builder.label :emergency_contact_num %><br />
        <%= builder.text_area :emergency_contact_num %><br />
      <% end %>
      <%= form.submit "Add", class: 'btn btn-primary' %><br />
    <% end %>

当我提交表单以创建新员工时,这就是我在控制台参数中得到的结果:

EmployeesController处理#create as HTML 参数:{&#34; UTF8&#34; =&GT;&#34;✓&#34;&#34; authenticity_token&#34; =&GT;&#34; IgYzybxM8 + M8jZ8NJgYKZ + Zhqr07kcV1e0QyWf&GT; uY8hQLyBY844jfOlLNl65F / 2RRr4TTW0F1MeSmDzVzBsXOjg ==&#34;,&#34; employee&#34; =&gt; {&#34; first_name&#34; =&gt;&#34; Firt Nam&#34;,&#34; middle&#34; =&gt;&#34; kk&#34;,&#34; last_name&#34; =&gt;&#34; jak&#34;,&#34; sex&#34; =&gt;&#34; dfkj&#34;,&#34; race&#34; =&gt;&#34; jkadflj&#34 ;,&#34; birthdate&#34; =&gt;&#34; 2011-01-01&#34;,&#34; employee_contacts&#34; =&gt; {&#34; street&#34; =&gt;& #34; afdjkljadfkl&#34;,&#34; city&#34; =&gt;&#34; jadklfjakldfj&#34;,&#34; state&#34; =&gt;&#34; fadjlkdf&#34;,&# 34; zip&#34; =&gt;&#34; 32787&#34;,&#34; phone_num&#34; =&gt;&#34; 567567567&#34;,&#34; alt_phone_num&#34; =&gt;& #34; 57875875875&#34;,&#34; email&#34; =&gt;&#34; dajkjdlkfj@jkj.com" ;,&#34; emergency_contact_first_name&#34; =&gt;&#34; adfjkladjf&#34 ;,&#34; emergency_contact_last_name&#34; =&gt;&#34; adfjkaldf&#34;,&#34; emergency_contact_num&#34; =&gt;&#34; 784339793&#34;}},&#34;提交&# 34; =&GT;&#34;添加&#34;}

Unpermitted parameter: :employee_contacts

因此它保存了员工,但没有保存与其联系信息相关的任何内容。如果我在Rails控制台中运行Employee.last,我会获得employee_contact_id的nil值。如果我尝试使用Rails控制台查找Employee_Contact.last或Employee_Contact.all,我将无法自动加载常量Employee_Contact,预期employee_contact.rb可以定义它&#39;。

更新

由于安东,我改变了一些事情。

我的员工联系模式现在继承自ApplicationRecord:

class EmployeeContact < ApplicationRecord
  belongs_to :employee, inverse_of: :employee_contact
end

我将employee_contact循环中的视图格式从复数更改为单数:

<%= form.fields_for :employee_contact do |builder| %>

我在Employee#New

中添加了一个构建方法
def new
  @employee = Employee.new
  @employee.build_employee_contact
end

编辑员工#Create

def create
  @employee = current_user.employees.create(employee_params)

  if @employee.valid?
  redirect_to root_path
    else
  render :new, status: :unprocessable_entity
  end
end

现在正在保存员工联系人。以下是控制台的结果:

#<EmployeeContact id: 1, street: "dafjkafdjl", city: "adjfklajdk", state: "dfjkljalkdfjioad", zip: "dafjadlkfjkajdkl", phone_num: "adf", alt_phone_num: "871274892174", email: "dafnajdklj@jkklda.com", emergency_contact_first_name: "ajdfjalkj", emergency_contact_last_name: "fjadkljdfkl", emergency_contact_num: "11287244", user_id: nil, employee_id: 1, created_at: "2017-10-03 19:01:55", updated_at: "2017-10-03 19:01:55">

Employee id: 1, first_name: "dafad", middle: "dfad", last_name: "dafd", sex: "adfd", race: "dfad", birthdate: "1210-01-01", user_id: 1, created_at: "2017-10-03 19:01:55", updated_at: "2017-10-03 19:01:55", employee_contact_id: nil>

Employee模型仍然获得Employee_Contact_Id:nil值。但是,Employee Contact模型正在获取正确的Employee_Id属性。

解决

因此,我将把它与我在更新中发布的内容保持一致。我的Employee模型不需要具有Employee_Contact_Id属性。当我创建新的员工时,联系人正确地映射到当前的员工。

1 个答案:

答案 0 :(得分:0)

请将EmployeeContact设置为继承自ApplicationRecord,而不是Employee 在新操作中,从员工构建嵌套表单的员工联系人 我建议从has_one关联中删除外键 employee_contact上的employee_id就足够了。