2012-02-02 58 views
0

我是Rails中的新手。我有三名桌球员,花名册和阵容。我有模型条目来创建玩家所属的阵容和阵容,阵容has_many球员和阵容has_many球员之间的关系。在Rails 3.1中创建一种向表中添加新记录的方法

我遇到的问题是当我创建名单时我有一个roster_name属性,我可以添加一个单一的球员。我想增加更多的球员到相同的花名册上,但我正在努力如何将新球员添加到花名册中。默认的新视图调用_form部分,它期望我创建一个全新的名单,这将允许我再次添加一个用户。

什么是轨道的方式来添加一个新的球员到现有名单。请帮我了解我需要什么组件。我是否需要一个新的部分,我可以打电话给一个领域添加新的球员?我必须创建一个新的方法或控制器吗?我所假设的是,我需要一种方法来引用现有名单,同时能够添加新的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协会经常被用来建立与其他模型中的许多一对多连接。该关联表明声明模型可以通过继续第三个模型与另一个模型的零个或多个实例进行匹配。现在,协会的声明看起来是这样的:

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。轨道投射的代码形式已被Ryan Bates提取出来,并且非常有用。

更新您的Gemfile需要这种宝石

gem 'nested_form' 
$> bundle install 

下运行发电机,以创建JavaScript文件。这会自动检测你是否使用jQuery或Prototype。

rails g nested_form:install 

运行发电机将增加应该包括了jQuery或Prototype框架后一个文件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 %> 

当这种形式呈现时,它会看起来像它以前做过的。这是因为一个新名单不会有任何与之相关的球员,因此没有任何球员领域会被显示。最终,我们希望在表单上有一个“添加玩家”链接,但我们可以在RosterController的新操作中创建一个roster_player,并显示其字段。

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

默认情况下嵌套属性的更新被关闭,您可以使用#accepts_nested_attributes_for类方法启用它。启用嵌套属性时,将在模型上定义属性编写器。这应该工作,并希望它有帮助。

+0

我似乎与嵌套属性范例冲突。在该示例中,它使用注释模型作为文章模型的嵌套属性。该评论仅与该文章有关。我想将player_id与名单关联起来,并且即使没有名单也让球员存在。所以在应用程序的使用中,玩家将首先被添加,然后创建名单以选择名单中的玩家。一些球员将不会在名册上,我计划拥有更多的球员名单。你发给我的例子仍然适合吗?我在访问播放器时遇到问题。 – RickO 2012-02-20 14:42:58

+0

使用关于模型结构的代码更新问题。 – 2012-02-21 06:34:51

+0

对不起,对于迟到的回复,我没有看到你的回复。我期待着一个独立的领域。这是我的代码。我试图通过id将许多球员添加到名册表中。我知道我的观点现在有缺陷。我希望在新阵容字段中有多个可用于玩家ID的字段,从集合选择下拉列表中选择玩家并添加每个填充的字段。 – RickO 2012-03-03 00:18:44

相关问题