2

私が仕事をすることができないコードの興味深い部分。私は次のモデル/関係を持っています (不要なコードを除く)

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' for #」エラーが返され、HABTM モデル間の結合テーブルだけが更新されません。これを解決する方法、または舞台裏で何が起こっているのか考えていますか? この手順の背後で起こっている「魔法」を理解して、それが機能していることを確認できるかどうかはわかりません。ほとんどの人は、HABTM はネストされた属性では機能しないと言っているようです。そうらしい。回避策はありますか?

4

2 に答える 2

1

これが Service モデルのコピー ペースト エラーではないと仮定すると、それが問題の原因である可能性があります。

 accepts_nested_attributes_for :services_subtypes

する必要があります

 accepts_nested_attributes_for :service_subtypes

accept_nested_attributes_for の最初の引数は、has_many、has_and_belongs_to_many、belongs_to ステートメントで定義された関連付けにする必要があります。

非表示フィールドの二重生成に関する 2 番目の小さな問題は、それを fields_for セクションに挿入したことにあります。fields_for には、id の非表示フィールドが自動的に含まれます。次のブロックから隠しフィールド行を安全に削除できるようにします。

<% fields.fields_for :service_subtypes do |subtype| %>
  <%= subtype.hidden_field :id %>
<% end %> 
于 2009-12-08T23:52:42.623 に答える
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

これは私が感じているちょっとしたハックであり、答えとして完全に満足しているかどうかはわかりませんが、送信時に再び service_subtype_ids に解析できるコンマ区切りのリストを非表示フィールドに入れます。

この余分な仮想パラメーターなしでそれを行う方法を誰かが知っているなら、私は知りたい.

助けてくれてありがとう。

于 2009-12-09T21:49:49.540 に答える