2011-08-03 40 views
0

私は親レコードと子レコードを同時に作成したいというフォームを持っています。簡単な例として、最初のEmployeeを持つ会社を挙げましょう。Railsを使った複雑なフォーム

def new 
    @company = Company.new 
    @company.employees.new 
end 

と、この私の見解では:

<%= form_for(@company) do |form| %> 

    <div> 
     <%= form.label :name %> 
     <%= form.text_field :name %> 
    </div> 

    <%= form.fields_for :employees do |employee_form| %> 

     <div> 
      <%= employee_form.label :name %> 
      <%= employee_form.text_field :name %> 
     </div> 

    <% end %> 

<% end %> 

と戻って私のコントローラでの再:

def create 
    @company = Company.new(params[:company]) 
    @company.employees << Employee.new(params[:company][:employees_attributes]["0"]) 

    # save stuff 
end 

質問1私のコントローラで

私は何かのように実行します。

フォームに作成された1人の従業員が移入される会社の従業員コレクションを取得できませんでした。私はparamsを見て、[:employees_attributes] ["0"]のものを見つけました。

私はうまくいっていますが、これを行うにきれいな方法がありますか?

質問2:

検証が従業員のために合格しない場合、私は一般的な取得の代わりに名前必要なバリデータメッセージの「従業員は無効です」。私はコレクション上でsaveを呼び出していますが、レールは検証エラーをバブリングするために最善を尽くしていますが、これを行うためのクリーンな方法がありますので、従業員固有のエラーを得ることができますか?

ショート

私はこれをクリーンアップすることができますどのように関連したモデルは、のparamsから自動的に作成され、私は、単一の従業員のための検証メッセージを取得するように。

ありがとうございます。

答えて

0

1)fields_forは、コントローラアクションに返されるparamsハッシュの親オブジェクト属性内に子オブジェクト属性がネストされるように調整します。 Railsに子オブジェクトを自動的に更新させるには、accepts_nested_attributes_for宣言を使用して、ネストされた属性を受け入れるように親モデルに指示します。

2)すべてのActiveRecordオブジェクトにエラーオブジェクトがあります。エラーリストをループしてメッセージを表示します。

これを達成する最良の方法は、エラーをレンダリングする部分ヘルパー・メソッドとビュー・ヘルパー・メソッドを作成することです。フォーム内の生成されたエラーメッセージをrender_error_messagesメソッドの呼び出しで置き換えます。生成されたフォームでこれを行うためのすべてのコードがあります。そのコードを部分的にリファクタリングするだけで、ヘルパーを作成する必要があります。これはパラメータとしてモデル名の配列を受け入れ、次に情報で必要なものを実行する必要があります。各モデルの一部をレンダリングしたり、子オブジェクトだけでなく親オブジェクトも処理する部分を描画したりします。完全にあなたの呼び出し。

3)それはむしろ構築するためにあなたの新しいアクションが新しい子オブジェクトを作成して変更しますので、代わりの

def new 
    @company = Company.new 
    @company.employees.new 
end 

この

def new 
    @company = Company.new 
    @company.employees.build 
end 

4を行う)accepts_nested_attributesは

をどのように動作するかを確認するために、これらのRailscastsを見ます

http://railscasts.com/episodes/196-nested-model-form-part-1

および

http://railscasts.com/episodes/197-nested-model-form-part-2

更新

それでは、どのように上記の情報は、あなたの質問に関連してあなたを残しありません。

1)私はうまく機能していますが、これを行うにはよりクリーンな方法がありますか?

新しいアクションを上記のポイント3のように修正しましたか?これで、作成アクションは次のようになります

def create 
    @company = Company.new(params[:company]) 

    # save stuff 
end 

これは、元の生成された作成アクションに戻ったので、はるかにクリーンです。 あなたはそれがアップデートの大部分であるとは思わないかもしれません。孤立していると、あなたは正しいでしょう。しかし、あなたが好きなだけ多くのfields_for宣言を広告に追加したいと思うほど多くの関係を追加できれば、ユーザーと従業員の関係をhas_manyに変えることができると考えてください。あなたはすべてそれを行うことができ、あなたの作成と更新アクションは正確に同じままで、それがよりクリーンなのです。

2)私は従業員に固有のエラーを得ることができるようにこれを行うクリーナーの方法はありますか? 私の回答が上記のポイント2であるとすれば、従業員オブジェクトだけでなくユーザーオブジェクトにもエラーオブジェクトがあることがわかりますか?また、エラーオブジェクトをループしてメッセージを正しく取得できるようになったことも知っていますか? は、だから、私はちょうどあなたがあなたのエラーメッセージが、あなたがからそれを呼び出すことができるパラメータとして任意のオブジェクトを取る部分にコードを表示するリファクタリングすべきであると言うことでしょう自分自身を繰り返すのリスクでこの

<% if @user.employee.errors.any? %> 
    <div id="error_explanation"> 
     <h2><%= pluralize(@user.employee.errors.count, "error") %> prohibited this user from being saved:</h2> 

     <ul> 
     <% @user.employee.errors.full_messages.each do |msg| %> 
     <li><%= msg %></li> 
     <% end %> 
     </ul> 
    </div> 
    <% end %> 

を行うことができますどのビューでも、すべてのフォームのスタイリングと機能を変更できます。

応答のための

+0

おかげで明確に願っています。私はすでに親モデルにaccepts_nested_attributes_forを設定しています。私はすでにmodel.errors.full_messages.eachを部分的に持っていますが、「名前は空白にできません」ではなく、「従業員は無効です」と表示されます。この2つの微妙なニュアンスを読んだら、ビルドの提案は意味があります。私はすでに助けを求める前にRailscastsを見てきました。それがどこに残っているのかわからない、他のアイデアはすばらしいが、他に何ができるかわからない。再度、感謝します。 – blu

+0

私はこれらの点をカバーしましたが、おそらく私は十分にはっきりしていないと言いました。 – jamesc

+0

@blu - 私は自分の答えを更新しました。うまくいけば、私はあなたに与えた情報をどのように使用するのかを見ることができます – jamesc

関連する問題