简体   繁体   English

Ruby on Rails应用程序上的AssociationTypeMismatch错误

[英]AssociationTypeMismatch Error on Ruby on Rails app

I am having problems with my ruby on rails app. 我在rails应用程序上的ruby有问题。 I have two models - 'patient' and 'address', a patient has one address, and an address belongs to a patient. 我有两个模型 - “患者”和“地址”,患者有一个地址,地址属于患者。

Patient.rb 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 Address.rb

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

Patient-controller.rb 患者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 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 -%>

Everytime I add a new patient an error is thrown. 每次我添加新患者时都会引发错误。 Here is a part of the error: 以下是错误的一部分:

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'

I am new to RoR and would like to learn the language through practice. 我是RoR的新手,希望通过练习来学习这门语言。 I want to know what might be wrong with the code. 我想知道代码可能有什么问题。 Thanks! 谢谢!

First your Patient model needs an accepts_nested_attributes_for 首先,您的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

Your controller can be simplified a great deal. 您的控制器可以简化很多。 There is no need to save the address separately since @patient.save will take care of that. 由于@patient.save将负责处理,因此无需单独保存地址。 You don't need to set the created_on attribute manually since it will be set automagically :) Also when @patient.save fails you probably want to render :action => 'new' and not redirect_to :action => 'new' . 您不需要手动设置created_on属性,因为它将自动设置:)当@patient.save失败时,您可能想render :action => 'new'而不是redirect_to :action => 'new' This will redisplay the form with any validation errors (redirect_to will not.) 这将重新显示带有任何验证错误的表单(redirect_to不会。)

Also note that i renamed your controller class to PatientsController instead of PatientController . 另请注意,我将您的控制器类重命名为PatientsController而不是PatientController This will be more in line with Rails' RESTful conventions and will also help you simplify your view a bit. 这将更符合Rails的RESTful约定,并且还可以帮助您简化视图。 If you do this you'll need a map.resources :patients in your routes.db file, and you'll need to rename your files too. 如果你这样做,你需要一个map.resources :patients 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

Your view has a small error. 您的视图有一个小错误。 It needs to be fields_for :address and not fields_for @address . 它需要是fields_for :address而不是fields_for @address Also since your controller is now RESTful your can remove the :url => { :action => "create" } part. 此外,由于您的控制器现在是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 -%>

Hope this helps :) 希望这可以帮助 :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM