0

私のアプリには、多数の (およびネストされた属性を受け入れる) パッケージを持つ Animal モデルがあります。私の動物コントローラーでは、次のアクションを作成して、通常の動物の編集に使用されるページとは別のページ (および別のユーザー ロール) で特定の動物 (およびネストされたパッケージ) の属性を編集できるようにしました。(明確にするために、animals#edit アクションとページ、および別のanimals#log アクションとページがあり、理想的には異なるユーザー ロールが動物に関するさまざまなものを編集できるようにします):

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

    if params[:animal]
      if @animal.update_attributes(params[:animal])
        # I want a basic reload (with flash) in cases of both success and failure.
        redirect_to log_path(@animal), notice: "Animal update successful!"
      else
        redirect_to log_path(@animal), notice: "Update unsuccessful. Contact admin"
      end
    end
end

私の個別の編集/更新アクション:

  def update
    @animal = Animal.find(params[:id])

    if @animal.update_attributes(params[:animal])
        redirect_to @animal, notice: "Animal was successfully updated."
    else
        render action: "edit"
    end
  end

def edit
    @animal = Animal.find(params[:id])
end

問題は、ログ ページ (以下のコード) で送信ボタンを押すと、ページが更新されることですが、a) 何の通知もなく (マイナーな問題)、b) さらに重要なことに、実際にパッケージ情報を更新しないことです。 . 重要なのは、animal.weight 属性 (ここで変更可能な唯一の ANIMAL 属性) を更新すると、それが機能することです。ネストされたパッケージ属性だけではありません。

ヘルプ?私は本当にここで困惑しています。私はそれを機能させようとして、これを永遠にいじっています。以下の関連する可能性のあるコード:

私のroutes.rbファイル(動物リソースの上)では:

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

ここに私のログビューがあります:

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

    <div style="width: 200px">
        <% if @animal.weight %>
            <%= "Weight: #{@animal.weight}lbs" %>
        <% else %>
            <%= f.label "Weight (in lbs)" %>
            <%= f.text_field :weight %>
        <% end %>
    </div>

    # I'm cycling through each bundle to group "identical" packages in a table (one per bundle).

    <% @animal.sold_bundles.each do |bundle| %> <!-- Packages are bundled by cut and prep notes -->
      <%= render partial: 'package_bundle', locals: {:bundle => bundle, :f => f} %><br>
    <% end %>

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

<% end %>

そして、これが各バンドルに対して呼び出される「package_bundle」パーシャルです。一部は編集可能 (空白の true_weight 値のため) で、一部は編集可能でないパッケージのテーブルを生成します。

<table class="table">
    <thead>
        <tr>
            <th>Cut Name</th>
            <th>Prep Notes</th>
            <th>Label</th>              
            <th>Actual Lbs</th>
            <th>Actual Oz</th>
        </tr>
    </thead>
    <tbody>
        <!-- list of specified packages -->
            <%= f.fields_for :packages, bundle do |p| %>
                    <tr>
                        <td><%= p.object.name %></td>
                        <td><%= "#{p.object.user.name.first(3).upcase}-#{p.object.id}" %></td>
                        <% if p.object.true_weight == nil || p.object.true_weight == 0 %>
                            <td colspan=1><%= p.text_field :actual_lbs %></td>
                            <td colspan=1><%= p.text_field :actual_oz %></td>
                        <% else %>
                            <td><%= p.object.true_weight.round(0) %> lb</td>
                            <td><%= ((p.object.true_weight % 1) * 16).round(2)%> oz </td>
                        <% end %>  
                    </tr>   
            <% end %>  

    </tbody>
</table>

編集 - リクエストに応じてより多くのコード

package.rb (関連するもののみ) -- 以下の落とし穴を回避しました (今回は、間違いなく以前にその間違いを犯しました)。ポンド/オンスをパーセントでポンドに変換する私の方法がここで責任を負う可能性がありますが、私には正しいように見えます:

class Package < ActiveRecord::Base
  attr_accessible :animal_id, :cut_id, :price, :line_id, :sold, :savings, :actual_lbs, :actual_oz, :true_weight
  attr_accessor :actual_lbs, :actual_oz
  belongs_to :animal
  belongs_to :cut
  belongs_to :line
  before_update :to_true

def to_true
    if self.sold
      if self.order.status > 1 # This is the case for any package loaded on the log page
        if self.actual_lbs && self.actual_oz
          unless self.true_weight && self.true_weight > 0 # Don't overwrite legit true weights
            percent = self.actual_oz / 16
            self.update_attribute(:true_weight, self.actual_lbs + percent)
          end
        end
      end
    end
  end

animal.rb (関連のみ):

class Animal < ActiveRecord::Base
  attr_accessible :breed, :name, :photo, :animal_type, :hanging_weight, :meat_weight,  
                  :weight, :ranch_id, :butcher_id, :cow_mult, :pig_mult, :packages_attributes,
                  :lamb_mult, :goat_mult, :host_id, :final_sale, :opening_sale, :open, :no_sales
  has_many :orders
  has_many :packages
  belongs_to :butcher
  belongs_to :ranch
  belongs_to :host
  after_create :create_packages

  accepts_nested_attributes_for :packages

サーバーログ(開発ログよりも理解しやすい)を見て、これの底にたどり着き、2つの奇妙なことに気づきました。エラーはまったくありませんが、1)ページをロードするとGETを実行するようですが、送信を押したときに要求されたPUTは実行されないようです.2)おそらく結果として、唯一のパラメータが渡されました(これは次のように渡されます) GET リクエストの一部) は動物の ID です。パッケージ属性は渡されません。

4

2 に答える 2

1

attr_accessorコールバックをトリガーしません。変数を「ダーティ」にする必要があります。詳細はこちら

あなたのpackage.rb

def actual_lbs=(val)
  true_weight_will_change!
  @actual_lbs=val
end

これにより、actual_lbs 変数を設定すると、データベース内の変数が「ダーティ」になり、コールバックが発生するようになります。

于 2012-11-30T16:40:39.043 に答える