2016-08-19 5 views
2

私は3つの関連性が深いオブジェクトを構築しようとしています。ユーザーは必要に応じてさらに多くの子オブジェクトを追加することができます。Rails:深い関連を構築するためのフォーム

class Template < ActiveRecord::Base 
    has_many :stacks, dependent: :destroy 
    accepts_nested_attributes_for :stacks, allow_destroy: true 
end 

class Stack < ActiveRecord::Base 
    belongs_to :template 
    has_many :boxes, dependent: :destroy 
    accepts_nested_attributes_for :boxes, allow_destroy: true 
end 

class Box < ActiveRecord::Base 
    belongs_to :stack 
    has_many :template_variables, dependent: :destroy 
    accepts_nested_attributes_for :template_variables, allow_destroy: true 
end 

class TemplateVariable < ActiveRecord::Base 
    belongs_to :box 
end 

は今、新しいテンプレートのための私のコントローラは、そのようになっています。私は私がこれを行うには良い方法があると思う作っているいくつかの障害物に当たってい

def new 
    @template = Template.new 
    stack = @template.stacks.build 
    box = stack.boxes.build 
    box.template_variables.build 
end 

Stackオブジェクトの下のオブジェクトは保存されません。コントローラーはすべての正しいパラメーターを許可します。

params.require(:template).permit(:name, 
    stacks_attributes: [:name, :direction, :order, :x, :y, :_destroy], 
    boxes_attributes: [:name, :_destroy], 
    template_variables_attributes: [:name, :box_name, :designator, :order_index, :_destroy]) 

それは私のフォームがちょうど必要なので、のようなパーシャルレンダリングされことができます:

<%= f.simple_fields_for :stacks do |stack| %> 
    <%= render 'stack_fields', f: stack %> 
<% end %> 

<%= link_to_add_fields '+ stack', f, :stacks %> 

とその後の関係はstack_fields部分のように、その内部にネストされている:

<div style='background: #ccc; padding: 1em;'> 
    <%= f.input :name %> 
    <%= f.input :direction %> 
    <%= f.input :order %> 
    <%= f.input :x %> 
    <%= f.input :y %> 
    <%= f.hidden_field :_destroy %> 
    <%= link_to 'x', '#', class: 'remove_fields' %> 

    <%= link_to_add_fields '+ box', f, :boxes %> 

    <%= f.simple_fields_for :boxes do |b| %> 
    <%= render 'box_fields', f: b %> 
    <% end %> 
</div> 

だから私の質問は本当にあります:私はこれと同じように闘うよりも、自分が望むものを達成するための良い方法がありますか?同様に、標準的なプラクティスや宝石や、「深い」オブジェクト関係の作成に役立つものがあるかもしれません。

+1

フォームとオブジェクトは入れ子になっています...しかし、permit/requireが同じ方法でネストされていないように見えます...サーバログに渡されたパラメータを見て、あなたの許可/要求構造と一緒に? –

+0

ああ、それは良い点だし、それはかなり意味がある。私は今すぐクイックテストを実行します。それでも、これは私が他のどこかでもっと良い方法で解決されたかもしれない何かを解決しているように感じます。 :) –

答えて

1

パラメタが正しく正しくネストされていないため、各オブジェクトはその親オブジェクト内にネストする必要があります。現在、それらはすべてテンプレート内にネストされています。試してみてください:一般的に深い関連が唯一の限り2としてのレベルを行くことをお勧めし

params.require(:template).permit(:name, 
    stacks_attributes: [ 
    :name, :direction, :order, :x, :y, :_destroy, 
    boxes_attributes: [ 
     :name, :_destroy, 
     template_variables_attributes: [ 
     :name, :box_name, :designator, :order_index, :_destroy 
     ] 
    ] 
    ] 
) 

。しかし時にはそれは避けられないこともあります。データモデリングのコンテキストを知らないと、代替アプローチが可能かどうかを検討することは困難です。

関連する問題