ruby-on-rails – Ruby on Rails应用程序上的AssociationTypeMismatch错误

我的 ruby在rails应用程序中遇到问题.我有两个模型 – “病人”和“地址”,病人有一个地址,一个地址属于病人.

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的新人,想通过实践学习语言.我想知道代码可能有什么问题.谢谢!

解决方法

首先,您的患者模型需要一个accepted_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会照顾这个.你不需要设置
created_on属性,因为它将被自动设置:)另外当@ patient.save失败时,你可能想要渲染:action => ‘new’而不是redirect_to:action => ‘新’.这将重新显示表单与任何验证错误(redirect_to不会.)

另请注意,我将您的控制器类重命名为PatientsController而不是PatientController.这将更符合Rails的RESTful约定,并且还将帮助您简化您的视图.如果你这样做,你需要一个map.resources:routes.db文件中的病人,你也需要重命名你的文件.

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 => “创建”}部分.

<%= content_tag('h3','Create New Patient') %>
<hr>
<% form_for @patient do |patient_form| -%>
    <%= error_messages_for :patient %>
    <%= patient_form.label :last_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 -%>

希望这可以帮助 :)

相关文章

validates:conclusion,:presence=>true,:inclusion=>{...
一、redis集群搭建redis3.0以前,提供了Sentinel工具来监控各...
分享一下我老师大神的人工智能教程。零基础!通俗易懂!风趣...
上一篇博文 ruby传参之引用类型 里边定义了一个方法名 mo...
一编程与编程语言 什么是编程语言? 能够被计算机所识别的表...
Ruby类和对象Ruby是一种完美的面向对象编程语言。面向对象编...