HABTM 二重ネストフィールド_for
-
18-09-2019 - |
質問
コードの興味深い部分があり、動作させることができません。以下のモデル/関係があります(不要なコードは除外されています)
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 はネストされた属性では機能しないとほとんどの人が言っているようです。どうやらそうです。回避策はありますか?
解決 2
メーラーにそのエラーが見つかりました。いずれにせよ、fields_for :subtypes は、私がやろうとしていることを認識するためのネストされた属性の魔法のための適切なパラメータをまだ生成していませんでした。
私が最終的に得たのは次のとおりです。
新しい.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 %>
サービス.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 に解析できます。
この追加の仮想パラメータを使用せずにそれを行う方法を知っている人がいたら、ぜひ知りたいです。
助けてくれてありがとう。
他のヒント
これはサービスモデルのコピーペースト誤差がないと仮定すると、それはあなたの問題の原因である可能性があります。
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 %>