2012-05-14 108 views
0

我现在这个挣扎,因为几天,最后编辑的has_many决定问,即使我觉得它不应该是很难实现的。如何通过关联

我使用轨道3.1和我希望能够在一个单一的形式编辑的has_many的连接表的一些记录:通过关联

我看了Ryan Bates' railscasts但是这不正是我是什么寻找,

然后我试图执行this solution看起来非常接近我所需要的,但它不是编辑连接表。

这是情景: 我的球员(谁是用户的sublass)谁有很多技能。每个玩家都有一个技能等级,作为一个整数(1到10)存储在player_skill模型中。

我能够创建并显示玩家的技能,我可以设置值,并将其存储在数据库中,但我不能从数据库中检索现有值,并将其作为在下拉菜单中选择值。这是我的模型:

class Player < User 

    has_many :player_skills, :dependent => :destroy 
    has_many :skills, :through => :player_skills 
    accepts_nested_attributes_for :skills 

    attr_accessible :player_skills 

end 

class Skill < ActiveRecord::Base 
    has_many :player_skills 
    has_many :players, :through => :player_skills 
end 


# This stores the skill level as integer 1..10 

class PlayerSkill < ActiveRecord::Base 
    belongs_to :player 
    belongs_to :skill 
end 

我希望能够通过每每项技能下拉菜单进行编辑在一个单一的形式指定玩家所有技能水平。现在我可以设置并将它们保存到数据库中,但是当我重新加载编辑表单时,我无法检索这些值。

这是我用它来创建编辑表单代码。我明白我的错误是在select的用户,我没有加载现有的值,但我不知道如何去做。

<h3><%= @user.first_name %> <%= @user.last_name %></h3> 
<% @skills = Skill.all %> 
<%= form_for @user, :url => updateplayerskills_path(@user) do |f| %> 


    <div class="field"> 
    <table border="1"> 
    <tr> 
     <td>Skill Name</td> 
     <td>Level</td> 

    </tr> 
    <% @skills.each do |skill| %> 
     <%= f.fields_for :player_skills do |builder| %> 
     <tr> 
     <td><%=h skill.name %></td> 
     <td> 

     #Here how can I load and display the existing level's value?? 
     #Shall I maybe use a different select method? 

     <%= f.select skill.id, 1..10 %>  
     </td> 
     </tr> 
     <% end %> 
    <% end %> 
    </table> 
    </div> 
    <div class="actions"> 
    <%= f.submit %> 
    </div> 
<% end %> 

任何帮助/提示非常感谢! 谢谢!

回答

2

我认为你需要声明 - accepts_nested_attributes_for为“player_skills”,而不是“技能”。

所以, 类球员<用户

 has_many :player_skills, :dependent => :destroy 
     has_many :skills, :through => :player_skills 
     accepts_nested_attributes_for :player_skills 

而且,当前的表单代码是这样的:

<% @skills.each do |skill| %> 
    <%= f.fields_for :player_skills do |builder| %> 
    <tr> 
     <td><%=h skill.name %></td> 
     <td> 
      <%= f.select skill.id, 1..10 %>  
     </td> 
    </tr> 
    <% end %> 
<% end %> 

我想应该是这样的,而不是:

<%= f.fields_for :player_skills do |builder| %> 
    <tr> 
     <td> 
      <%= builder.label :skill_id, "Skill" %> 
      <%= builder.select(:skill_id, options_for_select(Hash[(1..10).collect { |n| [n.to_s, n] }])) %>  
     </td> 
    </tr> 
<% end %> 

编辑:

如果你想生成一个恒定的选项列表 - 10,你可以定义常量在application_helper.rb

module ApplicationHelper 
    MAX_SKILL_ID = 10 
end 

然后在您的视图:

<%= f.fields_for :player_skills do |builder| %> 
    <tr> 
     <td> 
      <%= builder.label :skill_id, "Skill" %> 
      <%= builder.select(:skill_id, options_for_select(Hash[(1..ApplicationHelper::MAX_SKILL_ID).collect { |n| [n.to_s, n] }]), player_skill.level) %>  
     </td> 
    </tr> 
<% end %> 
+0

感谢萨里尔!我认为我们在那里。实际上,你的代码显示了从1到6的值(我有6个技能)的下拉菜单,但是我需要在那里显示player_skill.level的当前值和从1到10的值。我找到了**难看的**解决方案到目前为止是<%= builder.select skill.id,options_for_select([['1',1],['2',2],['3',3],['4',4],[ '5',5],['6',6],['7',7],['8',8],['9',9],['10',10]],player_skill。级别)%>' – moncino07

+0

@ moncino07,根据您需要的常数更新我的答案。希望能帮助到你。 – Salil