ruby-on-rails – 使用带有accepts_nested_attributes_for的Rail
发布时间:2020-12-17 03:50:59 所属栏目:百科 来源:网络整理
导读:我正在编写一个名为Person的简单Rails模型has_many:phone_numbers,我试图以复杂的形式保存电话号码,而无需手动编写setter方法. accepts_nested_attributes_for应该做我想要的但是我无法让它工作.这是我到目前为止的代码: 移民 class CreatePeople ActiveRe
我正在编写一个名为Person的简单Rails模型has_many:phone_numbers,我试图以复杂的形式保存电话号码,而无需手动编写setter方法. accepts_nested_attributes_for应该做我想要的但是我无法让它工作.这是我到目前为止的代码:
移民 class CreatePeople < ActiveRecord::Migration def self.up create_table :people do |t| t.string :first_name t.string :last_name t.integer :address_id t.string :email t.timestamps end end def self.down drop_table :people end end class CreatePhoneNumbers < ActiveRecord::Migration def self.up create_table :phone_numbers do |t| t.string :number,:limit => 10 t.string :extension,:limit => 5 t.string :description,:null => false t.integer :telephone_id t.string :telephone_type t.timestamps end end def self.down drop_table :phone_numbers end end 楷模 class Person < ActiveRecord::Base has_one :address,:as => :addressable,:dependent => :destroy has_many :phone_numbers,:as => :telephone,:dependent => :destroy accepts_nested_attributes_for :phone_numbers attr_protected :id validates_presence_of :first_name,:last_name,:email end class PhoneNumber < ActiveRecord::Base attr_protected :id belongs_to :telephone,:polymorphic => true end 视图 <% form_for @person,:builder => CustomFormBuilder do |f| %> <%= f.error_messages %> <%= f.text_field :first_name %> <%= f.text_field :last_name %> <% fields_for "person[address]",@person.address,:builder => CustomFormBuilder do |ff| %> <%= ff.text_field :address_1 %> <%= ff.text_field :address_2 %> <%= ff.text_field :city %> <%= ff.text_field :state %> <%= ff.text_field :zip %> <% end %> <h2>Phone Numbers</h2> <% @person.phone_numbers.each do |phone_number| %> <% fields_for "person[phone_numbers][]",phone_number,:builder => CustomFormBuilder do |ff| %> <%= ff.text_field :description %> <%= ff.text_field :number %> <%= ff.text_field :extension %> <% end %> <% end %> <%= f.text_field :email %> <%= f.submit 'Create' %> <% end %> 调节器 def new @person = Person.new @person.build_address @person.phone_numbers.build respond_to { |format| format.html } end def create @person = Person.new(params[:person]) respond_to do |format| if @person.save flash[:notice] = "#{@person.name} was successfully created." format.html { redirect_to(@person) } else format.html { render :action => 'new' } end end end 我已经验证正在创建phone_numbers =方法,但该帖子仍会导致: PhoneNumber(#69088460) expected,got HashWithIndifferentAccess(#32603050) RAILS_ROOT: H:/projects/test_project 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/association_collection.rb:319:in `replace' C:/Ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.3/lib/active_record/associations/association_collection.rb:319:in `each' C:/Ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.3/lib/active_record/associations/association_collection.rb:319:in `replace' C:/Ruby/lib/ruby/gems/1.8/gems/activerecord-2.3.3/lib/active_record/associations.rb:1290:in `phone_numbers=' 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' H:/projects/salesguide/app/controllers/accounts_controller.rb:46:in `new' H:/projects/test_project/app/controllers/accounts_controller.rb:46:in `create' 我可以通过手动编写phone_numbers =方法来实现这一点,但这会导致巨大的重复工作,我更愿意学习如何做到这一点.谁能看到我做错了什么? 解决方法
您忘记将fields_for称为人员表单上的方法.否则,您实际上并未在accept_nested_attributes_for上下文中使用fields_for.迈克尔的解决方案试图欺骗Rails将提交视为正确定义的accepts_nested_attributes_for表单.
您尝试执行的操作的正确语法是: parent_form_object.fields_for id,object_containing_values,{form_for options},&block 如果您提供符号作为id,您将发现代码看起来更简洁,更简单,包含Person模型中定义的子模型的关联名称. 此外,如果@ person.phone_numbers为空,您正在使用的每个块可能会导致问题.您可以确保至少有一组电话号码字段,其中的行与我使用的行类似 <% @phs = @person.phone_numbers.empty? ? @person.phone_numbers.build : @person.phone_numbers %> 通过所有更正,此代码将按您的要求执行. 视图 <% form_for @person,:builder => CustomFormBuilder do |f| %> <%= f.error_messages %> <%= f.text_field :first_name %> <%= f.text_field :last_name %> <% f.fields_for :address,:builder => CustomFormBuilder do |address_form| %> <%= address_form.text_field :address_1 %> <%= address_form.text_field :address_2 %> <%= address_form.text_field :city %> <%= address_form.text_field :state %> <%= address_form.text_field :zip %> <% end %> <h2>Phone Numbers</h2> <% @phs = @person.phone_numbers.empty? ? @person.phone_numbers.build : @person.phone_numbers %> <% f.fields_for :phone_numbers,@phs,:builder => CustomFormBuilder do |phone_number_form| %> <%= phone_number_form.text_field :description %> <%= phone_number_form.text_field :number %> <%= phone_number_form.text_field :extension %> <% end %> <%= f.text_field :email %> <%= f.submit 'Create' %> <% end %> 您可能会发现查看complex-form-examples repository on github的工作示例很有用.它还附带了代码,可以从视图/表单中为:has_many关系动态添加新条目. (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |