Ruby on Rails – 保存和更新连接表中的属性,其中包含多个=> through

为简化起见,我有3个表:

has_many:能力,通过=>:统计

能力

has_many:people,through =>:stats

统计

belongs_to:人

belongs_to:能力

统计数据有一个名为“评级”的额外属性。

我想做的是制作一个编辑人员表格,它始终列出数据库中当前的所有能力,并让我为每个人分配一个评级。

对于我的生活,我无法弄清楚如何做到这一点。 我在创建一个具有以下内容的新用户时设法让它工作:

(来自人民控制员)

def new @character = Character.new @abilities = Ability.all @abilities.each do |ability| @person.stats.build(:ability_id => ability.id ) end end From the people form:   
@ability.id, :index => nil %> nil %>

这成功地给了我一个能力列表,旁边有评级框,如果我正在创建一个新用户,我可以保存它们。

问题是,如果我然后加载编辑表单(使用相同的表单部分),它不会带回评级,如果我保存,即使具有完全相同的评级,它会在统计表中创建重复的条目,而不是更新它。

我意识到我是一个可怕的程序员,我可能这样做的方式不对,但是如何让编辑表单回忆起为该用户分配给每个能力的当前评级,其次如何让它更新如果人和能力的组合已经存在,那么评级而不是重复它?

不应该这样

 Character has_many :stats has_many :abilities, through => :stats Ability has_many :stats has_many :characters, through => :stats Stat belongs_to :character belongs_to :ability 

还有人或人物吗? 你可以不同地提到两者。 (我将在答案中使用Character)

我认为你已经违反了“我会尝试制作我的架构的简化版本,以试图说明一个问题但反而让事情变得更复杂,并通过搞砸它来解决问题所以它不会使感觉“综合症。 无论如何,我可以看到几个问题:

1)首先,你要在角色创建后立即添加所有可能的能力。 这很愚蠢 – 默认情况下它们应该没有能力,然后你为它们拥有的那些创建连接表记录(统计数据)(通过勾选表单中的复选框)。

2)操作像这样的连接记录的一种简单方法是利用has_many:abilities宏给你的“ability_ids =”方法 – 在api http://railsbrain.com/api/rails中称为“collection_ids =” -2.3.2 / DOC / index.html的θA = M001885&名称=的has_many

换句话说,如果你说

@ character.ability_ids = [1,12,30]

然后,它将在该角色和技能1,12和30之间进行连接,并删除该角色与上述列表中没有的异能之间的任何其他连接。 将此与以[]结尾的表单字段名称将其值放入数组的事实相结合,您可以执行以下操作:

 #controller def new @character = Character.new @abilities = Ability.all end #form <% @abilities.each do |ability| %> 
<%= t.label @ability.name %> <%= check_box_tag "character[ability_ids][]" %>
<% end %> #subsequent controller (create action) @character = Character.new(params[:character]) #totally standard code

请注意,这里根本没有提到统计数据。 我们在字符和能力之间指定我们想要的关联,并让rails处理连接。

Railscasts剧集196和197展示了如何以一种forms编辑多个模型。 显示的示例看起来与您正在尝试的内容类似,因此它可能会帮助您(同样的剧集:196,197)。