Ruby on Rails 应用程序上的 AssociationTypeMismatch 错误 [英] AssociationTypeMismatch Error on Ruby on Rails app
问题描述
我的 ruby on rails 应用程序出现问题.我有两个模型——病人"和地址",一个病人有一个地址,一个地址属于一个病人.
I am having problems with my ruby on rails app. I have two models - 'patient' and 'address', a patient has one address, and an address belongs to a 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
地址.rb
class Address < ActiveRecord::Base
belongs_to :patient
validates_associated :patient
end
患者控制器.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'
我是 RoR 的新手,想通过练习来学习语言.我想知道代码可能有什么问题.谢谢!
I am new to RoR and would like to learn the language through practice. I want to know what might be wrong with the code. Thanks!
推荐答案
首先你的 Patient
模型需要一个 accepts_nested_attributes_for
First your Patient
model needs an 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
会处理这些.你不需要设置created_on
属性是手动设置的,因为它会自动设置 :) 此外,当 @patient.save
失败时,您可能希望 render :action =>'new'
而不是 redirect_to :action =>'新'
.这将重新显示带有任何验证错误的表单(redirect_to 不会.)
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. 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'
. This will redisplay the form with any validation errors (redirect_to will not.)
另请注意,我将您的控制器类重命名为 PatientsController
而不是 PatientController
.这将更符合 Rails 的 RESTful 约定,也将帮助您稍微简化您的视图.如果您这样做,您将需要 routes.db
文件中的 map.resources :patients
,并且您还需要重命名您的文件.
Also note that i renamed your controller class to PatientsController
instead of PatientController
. This will be more in line with Rails' RESTful conventions and will also help you simplify your view a bit. 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.
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 =>{:动作=>创建"}
部分.
Your view has a small error. It needs to be fields_for :address
and not fields_for @address
. Also since your controller is now RESTful your can remove the :url => { :action => "create" }
part.
<%= 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 -%>
希望这有帮助:)
这篇关于Ruby on Rails 应用程序上的 AssociationTypeMismatch 错误的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!