2012-12-04 47 views
0

我正在最困难的时间才能正确呈现和更新。发生什么事情是因为我有一个多对多的关联,关联表包含多个属性。一个案例可以有多个屏幕,一个屏幕多个案例,以及一个案例的屏幕可以针对每个案例进行订购。另一个与我当前的设置有关的奇怪项目是关联表在每次提交表单时都没有清除旧的关联值。新值将被附加到表中。:has_many,:through =>具有多个属性的关联表格更新

类:

class Case < ActiveRecord::Base 
    attr_accessible :cases_screens_attributes 

    has_many :cases_screens 
    has_many :screens, :through => :cases_screens 

    accepts_nested_attributes_for :cases_screens, 
            :allow_destroy => true, 
            :reject_if => lambda { |p| p[:screen_id].nil? } 
end 

class Screen < ActiveRecord::Base 
    has_many :cases_screens 
    has_many :cases, :through => :cases_screens 
end 

class CasesScreen < ActiveRecord::Base 
    attr_accessible :order 

    belongs_to :case 
    belongs_to :screen 
end 

控制器:

# GET /cases/1/edit 
def edit 
    @case = Case.find(params[:id]) 
    @cases_screens = @case.cases_screens.order("cases_screens.[order] ASC") 
    @screens = Screen.where({:active => true}) 
end 

# PUT /cases/1 
# PUT /cases/1.json 
def update 
    @case = Case.find(params[:id]) 
    @cases_screens = @case.cases_screens.order("cases_screens.[order] ASC") 
    @screens = Screen.where({:active => true}) 

    respond_to do |format| 
     if @case.update_attributes(params[:case]) 
     format.html { redirect_to case_path(@case), :notice => t(:case_successfully_updated) } 
     format.json { head :no_content } 
     else 
     format.html { render :action => "edit" } 
     format.json { render :json => @case.errors, :status => :unprocessable_entity } 
     end 
    end 
end 

我在使用fields_for无济于事尝试过很多尝试。这是我目前在我的_form.erb.html文件中。最终目标是,在案例表格中,查看每个屏幕旁边带有复选框的所有屏幕列表。每个复选框还有一个关联的“订单”输入。提交后,cases_screens表格将被正确填充(如果不再选择旧值,则会删除旧值)。

<div class="controls"> 

    <% @screens.each do |s| %> 

    <label> 
     <%= check_box_tag("case[cases_screens_attributes][#{s.id}][screen_id]", s.id, @case.screen_ids.include?(s.id)) %> 
     <%= s.name %> 
    </label> 
     <%= select_tag("case[cases_screens_attributes][#{s.id}][order]", options_for_select([email protected], 2)) %> 
    <% end %> 

</div> 

我一直在这块墙上撞了我的头几天,我似乎无法做到。任何帮助那里将不胜感激。

附加说明:

我用简单的形式,我只是做了以下内容:

<%= f.association :screens %> 

,一切都按预期工作(没有顺序属性更新)。关联表被正确清理。当然,这是指向嵌套属性的方向作为罪魁祸首,但我不确定。

更新星期三10:45 我现在确信,这里发生的问题是缺少在窗体中存在cases_screens_id。通常在清理期间,rails会使用这个ID清理以前的条目,然后填充新的条目。由于我正在循环@screens,而不是当前存在的cases_screens(与案例相关),我无法在没有查询的情况下通过每行获取id。

我想现在,我的解决方案将写一个before_save方法到cases_screens,它将清理当前条目的cases_screens,然后允许新值填充。

更新1:15 我已经接近至少一个项目,因此只有在复选框被选中时才会插入记录。我在上面的Case类中添加了更新:reject_if。我仍然没有解决为什么只将值附加到表中,以及为什么以前的值不会被删除。

更新4:00 如果记录只被设置,我最近的尝试包括一个隐藏字段,其中包含cases_screens ID。这需要我在循环中创建一个子查询以获取当前的cases_screen_id。除了:reject_if参数之外,现在正在更新值。但是,当前的设定值不能再被移除。

我没有这样做的权利,它不感觉像铁轨般。这种情况下,我应该在控制器中手动处理数据吗?

+0

错误...应该不是'cases_screen'是复数,而你用'has_many'使用它?像'has_many:cases_screens'? – scaryguy

+0

我更新了代码,现在反映了我的模型(包括多元化)。它仍然表现得一样。 – Venice

回答

0

在这个时候,我正在粉饰这个设计问题。我现在用的

<% @case.cases_screens.each do |cs| %> 
    <%= hidden_field_tag("case[cases_screens_attributes][#{cs.id}][id]", cs.id) %> 
    <%= hidden_field_tag("case[cases_screens_attributes][#{cs.id}][screen_id]", cs.screen_id) %> 
    <%= hidden_field_tag("case[cases_screens_attributes][#{cs.id}][_destroy]", 1) %> 
    <label><%= check_box_tag("case[cases_screens_attributes][#{cs.id}][_destroy]", 0, @case.cases_screen_ids.include?(cs.id)) %> <%= cs.screen.name %></label> 
    <%= text_field_tag("case[cases_screens_attributes][#{cs.id}][ordinality]", cs.ordinality) %> 
    <% end %> 

这只会导致当前设置的情况下/屏幕linkups露面。用户需要通过单独的屏幕将特定的屏幕添加到案例中。

相关问题