0

多くのパッケージを持つモデル動物があるアプリがあります。特定の動物に関連付けられたパッケージのサブセットの :true_weight 属性を更新できるフォームを作成しようとしています。このフォームは、カスタム URL/アクション (表示/新規/編集などではありません) にあります。ほとんどのことを正しく行ったように感じますが、パッケージを更新していないだけです。私の (省略された) コードを以下に置き、何が機能し、何が機能していないかを説明します。これにはかなり困惑しています:

package.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. 送信すると、動物ショーのページ (!?!?) にリダイレクトされ、通常の更新アクションの後にフラッシュが表示されます。
  2. @animal.toggle!(:finalized) アクションは何もしていないようです。上記の 1 を考えると、ブール値が 2 回切り替えられているのではないでしょうか? 行ったり来たり?
  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 に答える