2009-07-23 11 views
9

私のRubyアプリケーションでRubyに問題があります。私は2つのモデルを持っています - 「患者」と「住所」、患者は1つの住所を持ち、住所は患者に属します。Ruby on RailsアプリケーションでAssociationTypeMismatchエラーが発生しました

Patient.rb

class Patient < ActiveRecord::Base 
    has_many :charge_slips 
    has_one :address 

    validates_presence_of :last_name 
    validates_presence_of :first_name 
    validates_presence_of :middle_name 

end 

Address.rb

class Address < ActiveRecord::Base 
    belongs_to :patient 
    validates_associated :patient 
end 

患者controller.rb

class PatientController < ApplicationController 
    def index 
    @title = "Outpatient Services - Patient" 
    @today = Date.today.to_formatted_s(:long) 
    @patients = Patient.find(:all) 
    end 

    def new 
    @patient = Patient.new 
    @address = Address.new 
    end 

    def create 
    @patient = Patient.new(params[:patient]) 
    @patient.created_on = Date.today.to_formatted_s(:long) 

    if @patient.save 
     @address = Address.new(params[:address]) 
     @address.patient_id = @patient.id 
     if @address.save 
     redirect_to :action => 'index' 
     else 
     redirect_to :action => 'new' 
     end 
     redirect_to :action => 'index' 
    else 
     redirect_to :action => 'new' 
    end 
    end 
end 

new.html.rb

<%= content_tag('h3', 'Create New Patient') %> 
<hr> 
<% form_for @patient, :url => { :action => "create" } do |patient_form| -%> 
    <%= error_messages_for :patient %> 
    <%= patient_form.label :last_name, 'Last Name:' %> <%= patient_form.text_field :last_name, :size => 30 %><br> 
    <%= patient_form.label :first_name, 'First Name:' %> <%= patient_form.text_field :first_name, :size => 30 %><br> 
    <%= patient_form.label :middle_name, 'Middle Name:' %> <%= patient_form.text_field :middle_name, :size => 30 %><br> 

    <fieldset> 
     <legend>Patient's Permanent Address</legend> 
     <%= error_messages_for :address %> 
     <% patient_form.fields_for @address do |address_fields| -%> 
      <%= address_fields.label :street_name, 'Street Name:' %> <%= address_fields.text_field :street_name %><br> 
      <%= address_fields.label :barangay, 'Barangay:' %> <%= address_fields.text_field :barangay %><br> 
      <%= address_fields.label :city_municipality, 'City/Municipality:' %> <%= address_fields.text_field :city_municipality %><br> 
      <%= address_fields.label :country, 'Country:' %> <%= address_fields.text_field :country %><br> 
      <%= address_fields.label :zip_cide, 'Zip Code:' %> <%= address_fields.text_field :zip_code %><br> 
     <% end -%> 
    </fieldset> 

    <%= submit_tag "Add Patient" %> 
<% end -%> 

新しい患者を追加するたびに、エラーがスローされます。以下はエラーの一部です:

ActiveRecord::AssociationTypeMismatch in PatientController#create 

Address(#31360520) expected, got HashWithIndifferentAccess(#23815500) 

RAILS_ROOT: C:/www/Outpatient Application Trace | Framework Trace | Full Trace 

C:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.3/lib/active_record/associations/association_proxy.rb:263:in `raise_on_type_mismatch' 
C:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.3/lib/active_record/associations/has_one_association.rb:52:in `replace' 
C:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.3/lib/active_record/associations.rb:1246:in `address=' 
C:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.3/lib/active_record/base.rb:2740:in `send' 
C:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.3/lib/active_record/base.rb:2740:in `attributes=' 
C:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.3/lib/active_record/base.rb:2736:in `each' 
C:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.3/lib/active_record/base.rb:2736:in `attributes=' 
C:/ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.3/lib/active_record/base.rb:2434:in `initialize' 
C:/www/Outpatient/app/controllers/patient_controller.rb:14:in `new' 
C:/www/Outpatient/app/controllers/patient_controller.rb:14:in `create' 

私はRoRを初めて使い、練習を通してその言語を習得したいと考えています。私はコードに何が間違っているのかを知りたい。ありがとう!

答えて

28

は、まずあなたのPatientモデルはaccepts_nested_attributes_for

class Patient < ActiveRecord::Base 
    has_many :charge_slips 
    has_one :address 

    validates_presence_of :last_name 
    validates_presence_of :first_name 
    validates_presence_of :middle_name 

    accepts_nested_attributes_for :address 

end 

あなたのコントローラは多くのことを簡素化することができる必要があります。 @patient.saveがそれを処理するので、アドレスを別々に保存する必要はありません。 属性を属性に設定する必要はありません。自動で設定されるためです。また、@patient.saveが失敗した場合、おそらくrender :action => 'new'ではなくredirect_to :action => 'new'になります。

コントローラクラスの名前をPatientControllerの代わりにPatientsControllerに変更したことにも注意してください。これは、RailsのRESTfulな規則に沿ったものになります。また、ビューを少し簡略化するのに役立ちます。これを行う場合は、routes.dbファイルにmap.resources :patientsが必要です。また、ファイルの名前を変更する必要があります。

class PatientsController < ApplicationController 
    def index 
    @title = "Outpatient Services - Patient" 
    @today = Date.today.to_formatted_s(:long) 
    @patients = Patient.find(:all) 
    end 

    def new 
    @patient = Patient.new 
    @patient.build_address 
    end 

    def create 
    @patient = Patient.new(params[:patient]) 

    if @patient.save 
     redirect_to :action => 'index' 
    else 
     render :action => 'new' 
    end 
    end 
end 

あなたの表示には小さな誤差があります。 fields_for :addressで、fields_for @addressでないことが必要です。また、コントローラがRESTfulになったので、:url => { :action => "create" }の部分を削除することもできます。

<%= content_tag('h3', 'Create New Patient') %> 
<hr> 
<% form_for @patient do |patient_form| -%> 
    <%= error_messages_for :patient %> 
    <%= patient_form.label :last_name, 'Last Name:' %> <%= patient_form.text_field :last_name, :size => 30 %><br> 
    <%= patient_form.label :first_name, 'First Name:' %> <%= patient_form.text_field :first_name, :size => 30 %><br> 
    <%= patient_form.label :middle_name, 'Middle Name:' %> <%= patient_form.text_field :middle_name, :size => 30 %><br> 

    <fieldset> 
     <legend>Patient's Permanent Address</legend> 
     <%= error_messages_for :address %> 
     <% patient_form.fields_for :address do |address_fields| -%> 
       <%= address_fields.label :street_name, 'Street Name:' %> <%= address_fields.text_field :street_name %><br> 
       <%= address_fields.label :barangay, 'Barangay:' %> <%= address_fields.text_field :barangay %><br> 
       <%= address_fields.label :city_municipality, 'City/Municipality:' %> <%= address_fields.text_field :city_municipality %><br> 
       <%= address_fields.label :country, 'Country:' %> <%= address_fields.text_field :country %><br> 
       <%= address_fields.label :zip_cide, 'Zip Code:' %> <%= address_fields.text_field :zip_code %><br> 
     <% end -%> 
    </fieldset> 

    <%= submit_tag "Add Patient" %> 
<% end -%> 

希望はこのことができます:)

関連する問題