HABTM双嵌套fields_for

时间:2009-12-08 21:22:31

标签: ruby-on-rails has-and-belongs-to-many nested-attributes

我无法工作的有趣代码段。我有以下模型/关系(排除不必要的代码)

class Service < ActiveRecord::Base
  belongs_to :service_category, :foreign_key => "cats_uid_fk"
  belongs_to :service_type, :foreign_key => "types_uid_fk"
  has_and_belongs_to_many :service_subtypes, :join_table => "services_to_service_subs"
  belongs_to :service_request, :foreign_key => "audits_uid_fk"

  accepts_nested_attributes_for :service_subtypes
end

class ServiceSubtype < ActiveRecord::Base
  belongs_to :service_types, :foreign_key => "types_uid_fk"
  has_and_belongs_to_many :services, :join_table => "services_to_service_subs"
end

显示所有这些信息的表单:

<% form_for(@request, :url => { :action => :create }) do |form| %>
 <table>   

...other data...

 <% form.fields_for :services do |fields| %>
  <%= fields.hidden_field :cats_uid_fk %>
  <%= fields.hidden_field :types_uid_fk %>
  <% fields.fields_for :service_subtypes do |subtype| %>
   <%= subtype.hidden_field :id %>
  <% end %> 
 <% end %>   

 <p>
   <%= form.submit "Create", :class=>"hargray" %>
 </p>         
<% end %> 

并且控制器处理提交:

def create
 logger.debug params[:service_request].inspect

 @request = ServiceRequest.new(params[:service_request])
 if session[:cus_id]
  @request.customer = Customer.find session[:cus_id]
 end

 begin      
  @request.save!
  flash[:notice] = "Information submitted successfully. You will be contacted by a customer service representative regarding the services you selected."
  redirect_to :controller => "customer", :action => "index"
 rescue Exception => exc
  flash[:notice] = "#{ format_validations(@request) } - #{exc.message}"
  render :action => "new"
 end

end

html看起来很干净:

<input id="service_request_services_attributes_0_cats_uid_fk" name="service_request[services_attributes][0][cats_uid_fk]" type="hidden" value="1" />
  <input id="service_request_services_attributes_0_types_uid_fk" name="service_request[services_attributes][0][types_uid_fk]" type="hidden" value="1" />
  <input id="service_request_services_attributes_0_service_subtypes_attributes_0_id" name="service_request[services_attributes][0][service_subtypes_attributes][0][id]" type="hidden" value="2" />
   <input id="service_request_services_attributes_0_service_subtypes_attributes_0_id" name="service_request[services_attributes][0][service_subtypes_attributes][0][id]" type="hidden" value="2" />
  <input id="service_request_services_attributes_0_service_subtypes_attributes_1_id" name="service_request[services_attributes][0][service_subtypes_attributes][1][id]" type="hidden" value="4" />
   <input id="service_request_services_attributes_0_service_subtypes_attributes_1_id" name="service_request[services_attributes][0][service_subtypes_attributes][1][id]" type="hidden" value="4" />

提交的参数如下所示:

{
...other data...
 "services_attributes"=> {
  "0"=> {
   "types_uid_fk"=>"1", 
   "service_subtypes_attributes"=> {
    "0"=>{"id"=>"1"}, 
    "1"=>{"id"=>"2"}, 
    "2"=>{"id"=>"3"}
   }, 
   "cats_uid_fk"=>"1"
  }
 }
}

我找回“未定义的方法'service_subtype'表示#”错误,唯一没有更新的表是HABTM模型之间的连接表。任何想法如何解决这个或幕后发生的事情?我不确定我是否理解这个程序背后发生的“魔力”才能看到它正常工作。似乎大多数人说HABTM不适用于嵌套属性。似乎是这样。解决方法?

2 个答案:

答案 0 :(得分:1)

假设这不是服务模型中的复制粘贴错误,它可能是您问题的根源。

 accepts_nested_attributes_for :services_subtypes

应该是

 accepts_nested_attributes_for :service_subtypes

accepts_nested_attributes_for的第一个参数应该是has_many,has_and_belongs_to_many或belongs_to语句定义的关联。

关于双重生成隐藏字段的第二个小问题来自于将其插入fields_for部分。 fields_for自动包含id的隐藏字段。从下一个块中删除隐藏的字段行是安全的。

<% fields.fields_for :service_subtypes do |subtype| %>
  <%= subtype.hidden_field :id %>
<% end %> 

答案 1 :(得分:0)

发现那个错误,在我的邮件中。 在任何情况下,fields_for:subtypes仍然没有为嵌套属性的魔力生成正确的参数来接收我想要做的事情。

我最终得到的是:

<强> new.erb

<% form.fields_for :services do |fields| %>
    <%= fields.hidden_field :wsi_web_serv_cats_uid_fk %>
    <%= fields.hidden_field :wsi_web_serv_types_uid_fk %>
    <%= fields.hidden_field :service_subs_hash %>
<% end %>

<强> service.rb

def service_subs_hash
    self.service_subtype_ids.join(", ")
end

def service_subs_hash=(ids)
    self.service_subtype_ids = ids.split(",")
end

这有点像我觉得的hackish,我不确定我是否完全满意它作为答案,但它在我的隐藏字段中放置了逗号分隔列表,我可以在提交时再次解析为service_subtype_ids。

如果没有这个额外的虚拟参数,任何人都知道怎么做,我很想知道。

感谢您的帮助。