Rails 3.2.1 verschachtelte form und accepts_nested_attributes_for gibt: :Client(xxxxx) erwartet, bekam array(xxxxx)"

Bitte helfen Sie mir zu verstehen, wohin ich gehe falsch, so viel, so dass ich diese Meldung wenn ich versuche meine Daten speichern-Anmeldeformular(komplexe form), sobald ich alle Daten eingegeben haben?

Habe ich fünf Modelle wie folgt:

class Contract < AR::Base
  has_many :clientlines
  has_many :codelines
  has_many :clients, :through => :clientlines
  has_many :codes, :through => :codelines

  accepts_nested_attributes_for :clientlines
end

class Clientline < AR::Base
  belongs_to :contract
  belongs_to :client

  accepts_nested_attributes_for :contract
end

class Client < AR::Base
  has_many :clientlines
  has_many :contracts, :through => :clientlines
end

class Codeline < AR::Base
  belongs_to :contract
  belongs_to :code
  units_alloc

  accepts_nested_attributes_for :code
end

class Code < AR::Base
  has_many :codelines
  has_many :contracts, :through => :codelines
end

Benutzte ich den folgenden Artikel als mein design Quelle:

http://rubysource.com/complex-rails-forms-with-nested-attributes/

In meiner app/Controllers/contracts_controller.rb habe ich Folgendes:

def new
  @contract = Contract.new
  4.times { @contract.codes.build }
  4.times { @contract.codelines.build }
end

def create
  @contract = Contract.new(params[:contract])
  if @contract.save
    flash[:success] = "New Contract has been saved"
    redirect_to @contract # this redirects to the contract show page
  else
    @title = "You have some errors"
    render 'new'
  end
end
.
.
.
end

Ich zusammen die komplexe form wie folgt:

- provide(:title, 'Add Contract')
%h2 New Contract
=form_for(@contract) do |f|
  =render 'shared/contract_error_messages', object: f.object
  =render 'fields', f:  f
  .actions
    = f.submit "Save", class: 'save strong round'

die teilweise _fields:

<fieldset><legend>Enter Contract Details</legend>
.field
  = f.label :name, "AuthNum"
  %br/
  = f.text_field  :authnum, :size => 10, :class => "ui-state-default"
.field
  = f.label :name, "Start Date"
  %br/
  = f.text_field  :st_date, :size => 12, :class => "ui-state-default"
.field
  = f.label :name, "End Date"
  %br/
  = f.text_field  :end_date, :size => 12, :class => "ui-state-default"
</fieldset>
<fieldset><legend>Enter Client Details</legend>
= f.fields_for :clients do |ff|
  .field
    = ff.label :name, "First Name"
    %br/
    = ff.text_field :f_name, :size => 15, :class => "ui-state-default"
  .field
    = ff.label :name, "MI"
    %br/
    = ff.text_field :mi, :size => 3, :class => "ui-state-default"
  .field
     = ff.label :name, "Last Name"
     %br/
     = ff.text_field :l_name, :size => 15, :class => "ui-state-default"
  .field
     = ff.label :name, "Birth Date"
     %br/
     = ff.text_field :birth_date, :size => 12, :class => "ui-state-default"
  .field
     = ff.label :name, "Address1"
     %br/
     = ff.text_field :address1, :size => 25, :class => "ui-state-default"
  .field
     = ff.label :name, "Address2"
     %br/
     = ff.text_field :address2, :size => 25, :class => "ui-state-default"
  .field
     = ff.label :name, "City"
     %br/
     = ff.text_field :city, :size => 15, :class => "ui-state-default"
  .field
     = ff.label :name, "ZipCode"
     %br/
     = ff.text_field :zip_code, :size => 10, :class => "ui-state-default"
  .field
     = ff.label :name, "State"
     %br/
     = ff.text_field :state, :size => 15, :class => "ui-state-default"
  .field
     = ff.label :name, "MedicareNum"
     %br/
     = ff.text_field :medicarenum, :size => 20, :class => "ui-state-default"
  .field
     = ff.label :name, "MedicaidNum"
     %br/
     = ff.text_field :medicaidnum, :size => 20, :class => "ui-state-default"
  .field
     = ff.label :name, "MemberNum"
     %br/
     = ff.text_field :membernum, :size => 20, :class => "ui-state-default"
  .field
     = ff.label :name, "SocSerCareMgr"
     %br/
     = ff.text_field :socsercaremgr, :size => 20, :class => "ui-state-default"
  .field
     = ff.label :name, "SSCM_Ph"
     %br/
     = ff.text_field :sscm_ph, :size => 15, :class => "ui-state-default"
  .field
     = ff.label :name, "NurseCareMgr"
     %br/
     = ff.text_field :nursecaremgr, :size => 20, :class => "ui-state-default"
  .field
     = ff.label :name, "NCM_Ph"
     %br/
     = ff.text_field :ncm_ph, :size => 15, :class => "ui-state-default"
  .field
     = ff.label :name, "EmergencyContact"
     %br/
     = ff.text_field :emergencycontact, :size => 20, :class => "ui-state-default"
  .field
     = ff.label :name, "EC_Ph"
     %br/
     = ff.text_field :ec_ph, :size => 15, :class => "ui-state-default"
  .field
     = ff.label :name, "PrimaryCarePhy"
     %br/
     = ff.text_field :primarycarephy, :size => 20, :class => "ui-state-default"
  .field
     = ff.label :name, "PCPhy_Ph"
     %br/
     = ff.text_field :pcphy_ph, :size => 15, :class => "ui-state-default"
</fieldset>
<fieldset><legend>Enter Billing Code Details</legend>
= f.fields_for :codes do |ff|
  .field
    = ff.label :name, "Code Name"
    %br/
    = ff.text_field :code_name, :size => 15, :class => "ui-state-default"
  .field
    = ff.label :name, "Status"
    %br/
    = ff.text_field :status, :size => 10, :class => "ui-state-default"
  .field
    = ff.label :name, "Description"
    %br/
    = ff.text_field :description, :size => 25, :class => "ui-state-default"
= f.fields_for :codelines do |ff|
  .field
    = ff.label :name, "Units Alloc"
    %br/
    = ff.text_field :units_alloc, :precision => 6, :scale => 2, :size => 10, :class => 
    "ui-state-default"
</fieldset>

Meine erste und unmittelbare problem ist, dass sobald ich alle Daten eingegeben haben, auf die form und drückte dann auf den button 'Speichern' erhalte ich die folgende:

ActiveRecord::Verein TypeMisMatch in ContractsController#Erstellen.
Client(#xxxxxx) erwartet, bekam Array(#xxxxxx).

Das andere problem ist, dass, wenn ich auch 'accepts_nested_attributes_for :codelines' in meinem Vertrag-Modell, die 'units_alloc" - Attribut verschwindet aus meinem Formular.

Jede Hilfe oder Anleitung wäre sehr geschätzt, die auf diese beiden Fragen. Ich habe einige Zeit damit verbracht zu Lesen, komplexe Formen, gesehen "komplexe Formen" railcasts und ich habe gelesen und wieder Lesen-Schienen-Führungen über die Verbände sowie die API-Dokumentation auf accepts_nested_attributes_for Methode. Offensichtlich ist mein Verständnis von diesen Konzepten sind noch nicht aufgegangen bis zu dem vollen Verständnis erforderlich, um diese Probleme zu lösen, daher mein Hilferuf.

Update
app/controllers/contracts_controller.rb

class ContractsController < ApplicationController

def index
  @contracts = Contract.paginate(page: params[:page])
end

def show
  @contract = Contract.find(params[:id])
end

def new
  @contract = Contract.new
  @contract.codes.build
  @contract.codelines.build
  @contract.clients.build
end

def create
  raise params[:contract].to_s ------ **this is line #19**
  @contract = Contract.new(params[:contract])
  if @contract.save
    flash[:success] = "New Contract has been saved"
    redirect_to @contract # this redirects to the contract show page
  else
    @title = "You have some errors"
    render 'new'
  end
end

def edit
  @contract = Contract.find(param[:id])
end

def update
  if @contract.update_attributes(params[:contract])
    flash[:success] = "Contract Profile updated"
    redirect_to @contract
  else
    render 'edit'
  end
end
end

Habe ich noch die "raise params[:Vertrag].to_s" als erste Zeile in meinem create-Aktion in der contracts_controller.rb und der Ausgang folgt:

RuntimeError in ContractsController#create

{"authnum"=>"700900", "st_date"=>"04/03/2012", "end_date"=>"06/29/2012", "clients"=> 
{"f_name"=>"Lefty", "mi"=>"L", "l_name"=>"Right", "birth_date"=>"07/18/1979", 
"address1"=>"54 Frosty Lane", "address2"=>"", "city"=>"Frave", "zip_code"=>"54806",
"state"=>"WI", "medicarenum"=>"789987456", "medicaidnum"=>"931579135", 
"membernum"=>"890333-3", "socsercaremgr"=>"Caring Serving",
"sscm_ph"=>"1-444-444-4444", "nursecaremgr"=>"Caring Nurse", 
"ncm_ph"=>"1-555-555-5555", "emergencycontact"=>"Quick Response", 
"ec_ph"=>"1-666-666-6666", "primarycarephy"=>"This One", "pcphy_ph"=>"1-777-777-7777"},
"codes"=>{"code_name"=>"S-5463", "status"=>"Active", "description"=>"Transition from
sch to mkt"}, "codelines"=>{"units_alloc"=>"80.00"}}

Rails.root: /home/tom/rails_projects/tracking
Application Trace | Framework Trace | Full Trace

app/controllers/contracts_controller.rb:19:in `create'

Request

Parameters:

{"utf8"=>"✓",
"authenticity_token"=>"/i21h2vwzuDPjIrCXzYEIAg41FnMxfGdCQQggjqcZjY=",
"contract"=>{"authnum"=>"700900",
"st_date"=>"04/03/2012",
"end_date"=>"06/29/2012",
"clients"=>{"f_name"=>"Lefty",
"mi"=>"L",
"l_name"=>"Right",
"birth_date"=>"07/18/1979",
"address1"=>"54 Frosty Lane",
"address2"=>"",
"city"=>"Frave",
"zip_code"=>"54806",
"state"=>"WI",
"medicarenum"=>"789987456",
"medicaidnum"=>"931579135",
"membernum"=>"890333-3",
"socsercaremgr"=>"Caring Serving",
"sscm_ph"=>"1-444-444-4444",
"nursecaremgr"=>"Caring Nurse",
"ncm_ph"=>"1-555-555-5555",
"emergencycontact"=>"Quick Response",
"ec_ph"=>"1-666-666-6666",
"primarycarephy"=>"This One",
"pcphy_ph"=>"1-777-777-7777"},
"codes"=>{"code_name"=>"S-5463",
"status"=>"Active",
"description"=>"Transition from sch to mkt"},
"codelines"=>{"units_alloc"=>"80.00"}},
"commit"=>"Save"}

Update 1

Änderte ich meine contracts_controller neue Aktion:

def new
  @contract = Contract.new

Bauen die codelines Objekt durch den Vertrag, dann bauen Sie die codes durch die codelines Objekt

  codelines = @contract.codelines.build
  codelines.codes.build

Bauen die clientlines Objekt durch den Vertrag, dann bauen die Kunden durch die clientlines Objekt

  clientlines = @contract.clientlines.build
  clientlines.clients.build
end

Ich habe auch meinen Vertrag Modells durch hinzufügen accepts_nested_attributes_for :clientlines, :codelines, sowie das hinzufügen der attr_accessor Linie.

class Contract < ActiveRecord::Base
  has_many :clientlines
  has_many :codelines
  has_many :clients, :through => :clientlines
  has_many :codes, :through => :codelines

  accepts_nested_attributes_for :clients
  accepts_nested_attributes_for :codes
  accepts_nested_attributes_for :clientlines
  accepts_nested_attributes_for :codelines

  attr_accessor :codes, :clients, :clientlines, :codelines
end

Ich habe jetzt nested_attribute_writers mit Vereins-Namen, die in meinem params aber jetzt mein Fehler hat sich verändert:

NoMethodError in ContractsController#new

undefined method `build' for nil:NilClass

Nun ist die Frage, "Ist es richtig, haben attr_accessor Referenzierung für alle Vereine?"
Die andere Frage die ich habe ist, "muss ich ein form_helper erstellen Datensätze für client-code, und codeline?" Der Grund warum ich Frage ist, dass es scheint, dass trotz der build-Aktion habe ich in meiner contracts_controller es scheint, dass es immer noch null.
Wenn die Antwort ja ist auf die zweite Frage können Sie mir einige Ressourcen, die mich führen würde, die in Gebäude ein form_helper? Ich bin der überprüfung RailsGuides.

Dank.

Update 2

Habe ich schon im Kreis, wechselte ich meine contracts_controller neue Aktion:

def new
  @contract = Contract.new

  @contract.codes.build
  @contract.clients.build
end

Ich habe auch meinen Vertrag Modell zurück zu:

class Contract < ActiveRecord::Base
  has_many :clientlines
  has_many :codelines
  has_many :clients, :through => :clientlines
  has_many :codes, :through => :codelines

  accepts_nested_attributes_for :clients
  accepts_nested_attributes_for :codes

  attr_accessible :clients_attributes, :codes_attributes etc
end

Schließlich entfernte ich den Abschnitt in meinen Augen teilweise, _fields.html-Code.haml, betraf, zu codelines, nämlich:

= f.fields_for :codelines do |ff| and the next four lines

und jetzt ist mein params hat die nötige "clients_attributes" und "codes_attributes", und als ein Ergebnis der form speichert, um die entsprechenden Tabellen. Ich habe noch einige Fragen, nämlich die extra-Attribut in codeline, 'units_alloc' und ein paar andere, aber die Dinge werden besser Aussehen.

Schreibe einen Kommentar