2012-02-02 16 views
0

私はRailsの初心者です。私は3テーブルの選手、ロスターとラインアップを持っています。私は、選手が属しているロースターとラインアップ、ロースターhas_many選手、そしてラインナップhas_many選手の関係を作成するためのモデルエントリーを持っています。Rails 3.1のテーブルに新しいレコードを追加するメソッドを作成する

私は名簿を作成したとき、私が持っている問題は、私はroster_name属性を持っていると私はそれにシングルプレイヤーを追加することができています。私は同じ選手にもっと多くの選手を追加したいが、私は選手に選手を追加する方法に苦労している。デフォルトの新しいビューでは、_formパーシャルが呼び出され、まったく新しいリストを作成することが期待されます。これにより、再び1人のユーザーを追加できます。

新しいプレイヤーを既存の名簿に追加するためのレール方法は何ですか?私が必要とするコンポーネントを理解するのを助けてください。私は新しいプレーヤーを追加するフィールドを持つために呼び出すことができる新しい部分が必要ですか?新しいメソッドやコントローラを作成する必要がありますか?私が前提としているのは、新しいplayer_idを追加できる間に既存の名簿を参照する方法が必要だということです。どんな助けも素晴らしいだろう。ここで

は私のモデル/コントローラとビュー以来

My model roster.rb 
class Roster < ActiveRecord::Base 
    has_many :players 

    accepts_nested_attributes_for :players, :allow_destroy => true 
end 
My model player.rb 
class Player < ActiveRecord::Base 
    belongs_to :roster 
end 
My controller rosters_controller.rb 
def new 
    @roster = Roster.new 
    @players = Player.all 
End 

My roster view 
<%= form_for(@roster) do |f| %>         
    <% if @roster.errors.any? %>          
    <div id="error_explanation">         
     <h2><%= pluralize(@roster.errors.count, "error") %> prohibited this roster from being saved:</h2> 

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

    <div class="field"> 
    <%= f.label :player_id %><br /> 
    <%= f.text_field :player_id %> 
    <%= collection_select("roster", "player_id", @players, "id", "gname") %> 
    </div> 
    <div class="field"> 
    <%= f.label :player_id %><br /> 
    <%= f.text_field :player_id %> 
    <%= collection_select("roster", "player_id", @players, "id", "gname") %> 

    </div> 

    <div class="actions"> 
    <%= f.submit %> 
    </div> 

答えて

0

でその多対多の関連、has_many :through協会は、多くの場合、他のモデルと多対多の接続を設定するために使用されます。この関連付けは、第3のモデルを進めることによって、宣言モデルが他のモデルの0個以上のインスタンスと一致し得ることを示す。今、協会の宣言は次のようになります。

class Roster < ActiveRecord::Base 
    has_many :roster_players 
    has_many :players, :through => :roster_players 
end 

class RosterPlayer < ActiveRecord::Base 
    belongs_to :roster 
    belongs_to :player 
end 

class Player < ActiveRecord::Base 
    has_many :roster_players 
    has_many :roster, :through => :roster_players 
end 

ステップ1: 相関モデルを生成します。

$> rails g model roster_player roster:references player:references 
$> rake db:migrate 

ステップ2:あなたは、ネストされた属性を受け入れるための方法である必要は何 。このrails castを通り、nested_attributesについて読んでください。 rails castがRyan Batesによって宝石として引き出されたコードフォームは非常に便利です。

次のJavaScriptファイルを作成するための発電機を実行して

gem 'nested_form' 
$> bundle install 

この宝石を必要とするように、あなたのgemfileを更新します。これは、jQueryまたはPrototypeを使用しているかどうかを自動的に検出します。

rails g nested_form:install 

ジェネレータを実行すると、jQueryのかプロトタイプフレームワークの後に含まれるべきファイルnested_form.jsを追加します。

<%= javascript_include_tag :defaults, "nested_form" %> 

私たちがここで何をしたいのか_roster_player_fields.html.erb

<div class="field"> 
    <%= f.label :player_id, "Player" %> 
    <%= f.select :player_id, Player.all.collect { |p| [ p.name, p.id ] }, { :include_blank => true } %> 
</div> 

という名前の部分にネストされた属性を抽出してみましょうフォームに名簿palyersのそれぞれのフィールドを追加することです。 fields_forメソッドを使用すると、関連するフィールドをフォーム内で管理し、関連付けられたモデルの名前を渡してから関連するすべてのプレーヤレコードをループし、それぞれのフォームビルダを作成できます。ビルダーは各プレーヤーのために部分をレンダリングします。

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

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

    <% f.fields_for :roster_players do |builder| %> 
    <%= render 'roster_player_fields', :f => builder %> 
    <% end %> 
    <%= link_to_add_fields "[+] Add Player", f, :roster_players %> 

    <div class="actions"> 
    <%= f.submit %> 
    </div> 
<% end %> 

このフォームをレンダリングすると、前と同じようになります。これは、新しい名簿には関連するプレイヤーがないため、プレイヤーフィールドのいずれも表示されないためです。最終的には、フォームに「Add Player」リンクが必要ですが、RosterControllerの新しいアクションではroster_playerを作成するだけで、そのフィールドが表示されます。デフォルトでは

def new 
    @roster = Roster.new 
    @roster.roster_players.build 
End 

ネストされた属性の更新は、あなたが#accepts_nested_attributes_forクラスメソッドを使用して、それを有効にすることができ、オフになっています。ネストされた属性を有効にすると、モデルに属性ライターが定義されます。これはうまくいくはずです。

+0

私はネストされた属性のパラダイムと競合しているようです。この例では、記事モデルへのネストされた属性としてコメントモデルを使用しています。コメントは記事に関連してのみ存在します。私は、player_idを名簿に関連させ、その名簿がなくてもプレーヤーを存在させたいと思います。したがって、アプリケーションの使用では、プレイヤーが最初に追加され、次にロスターが作成され、ロスターにあるプレーヤーが選択されます。いくつかの選手は選手名簿に載っていないだろう。あなたが私をまだ送ってくれた例はありますか?私はプレーヤーにアクセスする際に問題があります。 – RickO

+0

あなたのモデルがどのように構造化されているかに関するコードで質問を更新してください。 –

+0

遅く返事を申し訳ありません、私はあなたの返信を見ませんでした。私は別々のフィールドを期待していた。ここに私のコードです。私は多くの選手をIDでロスターテーブルに追加しようとしています。私の意見には今欠陥があることが分かっています。私は新しい選手フィールドでプレイヤーのIDが利用できるように多くのフィールドを持っていきたい、コレクションの選択ドロップダウンから選手を選択し、各入力フィールドを追加します。 – RickO