2

我无法工作的有趣代码片段。我有以下型号/关系(不必要的代码除外)HABTM双嵌套fields_for

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不适用于嵌套属性。似乎是这样。解决问题?

+0

刚刚实现了它的双重生成隐藏字段的子类型。任何想法为什么上面的代码会这样做? – Lukas 2009-12-08 21:24:15

回答

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。

如果有人知道如何做到这一点没有这个额外的虚拟参数,我很想知道。

感谢您的帮助。

1

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

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 %> 
+0

看起来像实际的错误是:错误输入用户: - 未定义的方法'service_subtype'为#<服务:0xb1b6cba8> – Lukas 2009-12-09 16:16:51

+0

删除了错字。是一个复制/粘贴错误。 – Lukas 2009-12-09 16:20:11

+0

您发布的代码不应导致该错误。也许有服务中的验证/回调调用service_subtype而不是service_subtypes? – EmFi 2009-12-09 16:29:04