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

时间:2010-11-16 03:41:33

标签: ruby-on-rails

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

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

能力

has_many:people,through => :统计

统计

belongs_to:人

belongs_to:abilities

Stats有一个名为'rating'的额外属性。

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

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

(来自人民控制人员)

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:

<% for @ability in @abilities do %>
    <%= fields_for "person[stats_attributes]" do |t| %>
 <div class="field">
    <%= t.label @ability.name %>
    <%= t.hidden_field :ability_id, :value => @ability.id, :index => nil %>
    <%= t.text_field :rating, :index => nil %>
  </div>
  <% end %>
  <% end %>

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

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

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

2 个答案:

答案 0 :(得分:1)

不应该是

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-2.3.2/doc/index.html?a=M001885&name=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| %>
  <div class="field">
    <%= t.label @ability.name %>
    <%= check_box_tag "character[ability_ids][]" %>
  </div>
<% end %>

#subsequent controller (create action)
@character = Character.new(params[:character]) #totally standard code

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

答案 1 :(得分:0)

Railscasts剧集196197展示了如何在一种形式中编辑多个模型。显示的示例看起来与您尝试的内容类似,因此它可能会帮助您(ascicasts上的相同剧集:196197)。