0

我有一个应用程序,其中有一个模型 Animal 有很多包。我正在尝试创建一个表单,其中可以更新与特定动物关联的包子集的 :true_weight 属性。此表单位于自定义 url/action 中(不是显示/新建/编辑或其他)。我觉得我做的大部分都是正确的,但它只是没有更新软件包。我将把我的(缩写的)代码放在下面,然后解释什么是有效的,什么是无效的。对此非常困惑:

包.rb

attr_accessible :true_weight # And irrelevant others
belongs_to :animal

动物.rb

attr_accessible :finalized, :name # And irrelevant others
has_many :packages
accepts_nested_attributes_for :packages

路线.rb

match '/animals/:animal_id/log' => "animals#log"

动物/log.html.erb

<%= form_for(@animal) do |f| %> 

<div style="width: 200px">
        <%= f.label :name %>
        <%= f.text_field :name %>
</div>

    # This produces the subset of packages I want to be able to edit. It's an array
    # of arrays, so that each render produces a separate table made from one of the 
    # inner arrays.
<% @animal.packages_for_log.each do |bundle| %> 
    <%= render partial: 'package_bundle', locals: {:bundle => bundle} %><br>
<% end %>

<h4>And then you'd allow addition of extra packages here.</h4>

<%= f.submit "Submit Animal Log", :class => "btn image-button right" %>

<% end %>

_package_bundle.html.erb

<table class="table">
    <thead>
        <tr>
            <th>Name</th>
            <th>Notes</th>
            <th>Label</th>
            <th>True Weight></th>
        </tr>
    </thead>
    <tbody>
        <% bundle.each do |package| %> <!-- Produces for each "bundle" the list of identical packages -->
            <%= fields_for package do |p| %>
                <% if package.order.user %>
                    <tr>
                        <td><%= package.name %></td>
                        <td><%= package.line.processed_notes %></td>
                        <td><%= "#{package.order.user.name.first(3).upcase}-#{package.id}" %></td>
                        <% if !package.true_weight %>
                            <td colspan=1><%= p.text_field :true_weight %></td
                        <% else %>
                            <td><%= package.true_weight.round(0) %>lb</td>

                        <% end %>  
                    </tr>
                <% end %>
            <% end %>   
        <% end %>
    </tbody>
</table>

Animals_controller.rb(日志是动物动作/视图)

def log
    @animal = Animal.find(params[:animal_id])

    if @animal.update_attributes(params[:animal])
      puts "Inside If Block"
      @animal.toggle!(:finalized)
    else
      # I don't know about this. I wanted to redirect to the updated log page, with a flash
      # but when I last tried that, it had some recursive error, or would update without my 
      # submitting.
      render action: "log"
    end

  end

所以。什么工作:

  1. 正在访问我的动物控制器中的 if 块。但看起来它可能在我点击我的日志页面上的提交之前被访问。(我搜索并发现将行放入服务器日志中)。可能只是误读了。
  2. 表单元素看起来不错。我在正确的位置获得了一大堆文本框,并且每个包裹的信息都打印到文本字段旁边的表格中的页面上是正确的。
  3. 如果我在表格顶部填写动物名称属性,则(动物的)该属性将更新。

什么不起作用:

  1. 当我提交时,它会将我重定向到动物表演页面 (!?!?),并在常规更新操作后显示 Flash。
  2. @animal.toggle!(:finalized) 动作似乎没有做任何事情。也许,鉴于上面的 1,该布尔值被切换了两次?来回?
  3. 最重要的是——它根本不会更新我的包。

任何想法这里发生了什么,或者我需要添加什么?我真的很困惑我做错了什么。

谢谢!

编辑——根据请求,为我的 packages_for_log 方法添加代码(在 animal.rb 文件中)

def packages_for_log 
    master = []
    self.packages.each do |p|
      if p.sold

        # The master has sublists
        if master.any?
          counter = 0

          # Check for matching list. Add if found.
          master.each do |list|
            if p.notes == list.first.notes && p.type == list.first.type
              list << p
              counter += 1 # Don't create list is appropriate one found.
            end
          end
          if counter == 0
            master << [p] if counter == 0 # Add as new list if list doesn't yet exist.
          end
        else # If master is empty, add the package to a new sub-list.
            master << [p]
        end

      end

    end
    master.sort
  end

基本上,包有类型和注释。我希望日志为每个包类型/注释创建一个单独的表。所以我创建了一个数组,然后用所有包共享相同类型/注释的数组填充它。(首先,我确保它们都已售出。我不希望日志页面显示未售出的包裹。)

4

1 回答 1

1

我认为这里的问题:

<%= form_for(@animal) do |f| %>

默认使用此定义,Rails 将使用表单信息创建或更新记录,因此当您提交表单时,rails 检查这不是新记录,它执行的是update操作,而不是log操作。尝试更改为:

<%= form_for(@animal), :url => { :action => "log" }  do |f| %>

并再次提交表单并检查它是否有效。

编辑:您不用于fields_for

<% @animal.packages_for_log.each do |bundle| %> 
  <%= render partial: 'package_bundle', locals: {:bundle => bundle} %><br>
<% end %>

添加fields_for并重试:

<%= fields_for @animal.packages_for_log.each do |bundle| %> 
  <%= render partial: 'package_bundle', locals: {:bundle => bundle} %><br>
<% end %>
于 2012-11-08T22:04:15.073 回答