Rails 4 simple_form参数未保存到数据库

时间:2014-08-17 07:09:31

标签: ruby-on-rails simple-form

作为RoR的新手我正在创建一个网站,允许客户在线填写大型表格。该表单包含一些嵌套模型,但我的问题是客户端没有保存到表单提交的数据库中。

通过查看我的服务器,似乎params正在接收客户端信息,但是当sql操作启动时,它不会将任何信息插入到数据库中。虽然它表示它提交了事务,但我在rails控制台中的客户端具有所有nil属性。

    Started POST "/clients" for 192.168.1.114 at 2014-08-16 23:40:14 -0700
Processing by ClientsController#create as HTML
  Parameters: {"utf8"=>"✓", "authenticity_token"=>"2tPnVc7Aj5mMdd9ZnXVuFHHs3CprND6QZ8qyCxSC674=", "client"=>{"name"=>"Jon", "birthdate"=>"August 2 1990", "has_guardian"=>"0", "guardian"=>{"name"=>"", "phone_number"=>"", "relationship"=>"", "address"=>"", "birthdate"=>""}, "gender"=>"male", "relationship"=>"single", "address"=>"25 Oak Road, LA, CA, 90003", "home_phone"=>"3105636778", "home_phone_manner"=>"leave_message_with_info", "preferred_home_phone"=>"false", "confidential_home_phone"=>"false", "cell_work_phone"=>"3104556721", "cell_work_phone_manner"=>"leave_message_with_info", "preferred_cell_work_phone"=>"true", "confidential_cell_work_phone"=>"true", "email"=>"jon@gmail.com", "confidential_email"=>"true", "written_communication"=>"use_email", "family_contact"=>{"name"=>"Lily Mod", "phone_number"=>"3109776663"}, "additional_info"=>"Test", "created_at(1i)"=>"2014", "created_at(2i)"=>"8", "created_at(3i)"=>"17", "employer"=>"Polly", "occupation"=>"Sales", "prescriptions"=>"None", "medicines"=>"None", "allergies"=>"None", "conditions"=>"None"}, "commit"=>"Create Client"}
    Unpermitted parameters: has_guardian, guardian, family_contact, created_at(1i),       created_at(2i), created_at(3i)
  (0.1ms)  begin transaction
  SQL (0.4ms)  INSERT INTO "clients" ("additional_info", "created_at", "updated_at")          VALUES   (?, ?, ?)  [["additional_info", "Test"], ["created_at", Sun, 17 Aug 2014 06:40:14 UTC  +00:00], ["updated_at", Sun, 17 Aug 2014 06:40:14 UTC +00:00]]
  (0.6ms)  commit transaction
 Redirected to http://192.168.1.114:3000/
 Completed 302 Found in 59ms (ActiveRecord: 1.5ms)

当我在我的客户端内部进行pry时#craw在@client上显示所有nil属性,但当我在@client上调用类似于name的方法时,它会返回params中的值。

26:   def create
27:     @client = Client.new(client_params)
=> 28: binding.pry
29:     respond_to do |format|
30:       if @client.save
31:         format.html { redirect_to root_path, notice: 'Client was successfully created.' }
32:         format.json { render controller: :static_pages, action: 'home', status: :created, location: root_path }
33:       else
34:         format.html { render action: 'new' }
35:         format.json { render json: @client.errors, status: :unprocessable_entity }
36:       end
37:     end
38:   end

[1] pry(#<ClientsController>)> @client
=> #<Client id: nil, name: nil, email: nil, home_phone: nil, home_phone_manner: nil, cell_work_phone: nil, cell_work_phone_manner: nil, written_communication: nil, confidential_email: nil, additional_info: "test", birthdate: nil, gender: nil, relationship: nil, employer: nil, occupation: nil, medicines: nil, allergies: nil, conditions: nil, created_at: nil, updated_at: nil, preferred_home_phone: nil, confidential_home_phone: nil, preferred_cell_work_phone: nil, confidential_cell_work_phone: nil, prescriptions: nil, address: nil>
[2] pry(#<ClientsController>)> @client.name
=> "Jon"

我的相关客户控制器:

 def new
   @client = Client.new
 end

 def create
   @client = Client.new(client_params)

   respond_to do |format|
     if @client.save
       format.html { redirect_to root_path, notice: 'Client was successfully created.' }
       format.json { render controller: :static_pages, action: 'home', status: :created,     location: root_path }
     else
       format.html { render action: 'new' }
       format.json { render json: @client.errors, status: :unprocessable_entity }
     end
   end
 end
 def client_params
   params.require(:client).permit(:name, :email, :address, :home_phone, :home_phone_manner,
                                 :cell_work_phone, :cell_work_phone_manner,
                                 :written_communication, :confidential_email,
                                 :additional_info, :birthdate, :gender, :relationship,
                                 :prescriptions, :employer, :occupation, :medicines,
                                 :allergies, :conditions, :preferred_home_phone,
                                 :confidential_home_phone, :preferred_cell_work_phone,
                                 :confidential_cell_work_phone)
 end

我的路线档案:

  match '/contact', to: 'static_pages#contact', via: :get
  match '/about', to: 'static_pages#about', via: :get
  match '/contact', to: 'static_pages#about', via: :get

  match '/forms', to: 'clients#new', via: [:get, :post]

  resources :clients
  resources :family_contacts
  resources :guardians

我的客户端模型,我意识到我还没有完成所有工作以使协会工作但我现在只关心保存客户端:

  class Client < ActiveRecord::Base

    has_one :guardian

    has_many :family_contacts

    accepts_nested_attributes_for :family_contacts
    accepts_nested_attributes_for :guardian

    attr_accessor :name, :email, :birthdate, :gender, :address
    attr_accessor :home_phone, :home_phone_manner, :confidential_home_phone, :preferred_home_phone
    attr_accessor :cell_work_phone, :cell_work_phone_manner, :confidential_cell_work_phone, :preferred_cell_work_phone
    attr_accessor :written_communication, :confidential_email
    attr_accessor :relationship, :employer, :occupation
    attr_accessor :prescriptions, :medicines, :allergies, :conditions

    def has_guardian?
      self.guardian.present?
    end

 end

我的表单很长,但我试图通过取出很多样式和标签来简化它:

    <%= simple_form_for(@client, defaults: { required: false }, html: { class: 'form-inline' }) do |f| %>

    <%= f.input :name, label: "Patient's Name:", placeholder: "First & Last" %>

    <%= f.input :birthdate, label: "Birthdate:", placeholder: "January 1 2000" %>

    <%= f.input :has_guardian?, label: "Are you under the age of 18?", as: :boolean %>

      <%= f.simple_fields_for Guardian.new do |g| %>
        <%= g.input :name, label: "Name of Gaurdian", placeholder: "First & Last" %>
        <%= g.input :phone_number, label: "Phone # of Guardian", as: :tel %>
        <%= g.input :relationship, label: "Relationship to Patient" %>
        <%= g.input :address, label: "Guardian's Address" %>
      <% end %>

    <%= f.collection_radio_buttons :gender, [['male', 'Male'], ['female', 'Female']], :first, :last %>

    <%= f.collection_radio_buttons :relationship, [['single', 'Single'], ['married', 'Married'], ['widowed', 'Widowed'], ['seperated', 'Seperated'], ['domestic_relationship', 'Domestic Relationship']], :first, :last %>

    <%= f.input :address, lable: "Home Address:", placeholder: '25 Oak Road, Los Angeles, CA, 90003' %>

    <%= f.input :home_phone, label: "Home Phone #", as: :tel %>

    <%= f.collection_radio_buttons :home_phone_manner, [['leave_message_with_info', 'Leave message with detailed information.'], ['leave_message_with_callback', 'Leave message with call-back number only.']], :first, :last %>

    <%= f.collection_radio_buttons :preferred_home_phone, [[true, 'Yes'], [false, 'No']], :first, :last %>

    <%= f.collection_radio_buttons :confidential_home_phone, [[true, 'Yes'], [false, 'No']], :first, :last %>

    <%= f.input :cell_work_phone, label: "Cell/Work Phone #", as: :tel %>

    <%= f.collection_radio_buttons :cell_work_phone_manner, [['leave_message_with_info', 'Leave message with detailed information.'], ['leave_message_with_callback', 'Leave message with call-back number only.']], :first, :last %>

    <%= f.collection_radio_buttons :preferred_cell_work_phone, [[true, 'Yes'], [false, 'No']], :first, :last %>

    <%= f.collection_radio_buttons :confidential_cell_work_phone, [[true, 'Yes'], [false, 'No']], :first, :last %>

    <%= f.input :email, label: "Email:", as: :email %>

    <%= f.collection_radio_buttons :confidential_email, [[true, 'Yes'], [false, 'No']], :first, :last %>

    <%= f.collection_radio_buttons :written_communication, [['mail_home', 'Mail to my home address (above).'], ['mail_work', 'Mail to my work address.'], ['fax_to_home', 'Fax to me home phone (above).'], ['use_email', 'Email me to the above email address.']], :first, :last %>

  <%= f.simple_fields_for FamilyContact.new do |c| %>

      <%= c.input :name, label: "Name:", placeholder: "First & Last" %>

      <%= c.input :phone_number, label: "Phone #", as: :tel %>

      <%= c.input :name, label: "Name:", placeholder: "First & Last" %>

      <%= c.input :phone_number, label: "Phone #", as: :tel %>

  <% end %>

  <%= f.input :additional_info, label: "Additional Information:", as: :text %>

    <%= f.input :created_at, label: "Date", as: :date %>

    <%= f.input :employer, label: "Employer:" %>

    <%= f.input :occupation, label: "Occupation:" %>

    <%= f.input :prescriptions, label: "Current Prescription Medications:" %>

    <%= f.input :medicines, label: "Over the Counter Medications:" %>

    <%= f.input :allergies, label: "Allergies to Medications" %>

    <%= f.input :conditions, label: "Other Medical Conidtions" %>

    <%= f.input :created_at, label: "Date", as: :date %>

  <%= f.simple_fields_for Guardian.new do |g| %>
    <%= g.input :name, label: "Name of Gaurdian", placeholder: "First & Last" %>
    <%= g.input :birthdate, label: "Birthdate of Guardian", placeholder: "January 1 2000" %>
  <% end %>

  <%= f.input :name, label: "Patient's Name:", placeholder: "First & Last" %>
  <%= f.input :birthdate, label: "Birthdate:", placeholder: "January 1 2000" %>

  <%= f.submit %>
  

很抱歉文件的长度,但我真的很感激任何帮助。感谢

1 个答案:

答案 0 :(得分:0)

这是错误:

  

未经许可的参数:has_guardian,guardian,family_contact,   created_at(1i),created_at(2i),created_at(3i)

虽然上面的错误是strong_params,但我认为这是我们需要解决的更深层次的问题。当你是新手时,让我详细介绍一下这对你有用......


<强>属性

您拥有的模型中充满了attr_accessorattr_accessor是一种创建虚拟属性&#34;的方法。在Ruby / Rails中,因为它定义了一个custom getter and setter method,它基本上定义了&#34;属性&#34;用于系统

您遇到的问题是attr_accessor,用最简单的术语来说,不允许将数据保存在数据库中。这将是您遇到的更大问题之一 - 您需要摆脱覆盖数据库属性的任何attr_accessors

这在此处得到证明:

  

INSERT INTO&#34;客户&#34; (&#34; additional_info&#34;,&#34; created_at&#34;,&#34; updated_at&#34;)   VALUES(?,?,?)[[&#34; additional_info&#34;,&#34; Test&#34;],[&#34; created_at&#34;,Sun,   2014年8月17日06:40:14 UTC +00:00],[&#34; updated_at&#34;,Sun,2014年8月17日   06:40:14 UTC +00:00]]

这基本上表明只有additional_infocreated_atupdated_at填充数据库。

您应该从attr_accessor模型中删除Client方法:

#app/models/client.rb
class Client < ActiveRecord::Base

    has_one :guardian

    has_many :family_contacts

    accepts_nested_attributes_for :family_contacts
    accepts_nested_attributes_for :guardian

end

<强>未经许可

未经许可的参数问题主要是由您在强params散列中未经许可而导致的。您需要在此处添加它们:

#app/controllers/clients_controller.rb
Class ClientsController < ApplicationController
   private

   def client_params
      params.require(:client).permit(..., :has_guardian, :guardian, :family_contact, :created_at(1i), :created_at(2i), :created_at(3i))
   end
end

虽然情况确实如此,但我觉得您尝试通过的属性数量存在很大问题。它不违反惯例或任何内容,但验证每个提交的所有属性肯定会导致问题吗?

我说它unworkable - 你最好把它分成可管理的相关模型/对象,不过我会把它留给你来解决