Rails自定义嵌套更新未更新



我的应用程序有一个Animal模型,它有许多(并接受嵌套属性)程序包。在我的Animals Controller中,我创建了以下操作,以允许在一个单独的页面中编辑某些Animal(和嵌套的Package)属性(并用于单独的用户角色),而不是用于正常的Animal编辑。(为了澄清,我有一个动物#编辑动作和页面,以及一个单独的动物#日志动作和页面。理想情况下,它允许不同的用户角色编辑关于动物的不同内容):

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 %>

这是为每个bundle调用的"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>

EDIT--请求时提供更多代码

package.rb(只是相关的)——我避开了下面的gotcha(这次;我以前肯定犯过那个错误)。有一种可能性是,我将磅/盎司转换为带有百分比的磅的方法是罪魁祸首,但在我看来是正确的:

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

查看我的服务器日志(对我来说比开发日志更容易理解),了解这一点,并注意到两件奇怪的事情。没有任何错误,但1)当我加载页面时,它似乎执行了页面的GET,但当我点击submit时,它没有执行请求的PUT,2)因此,可能唯一传递的参数(作为GET请求的一部分传递)是动物id;不传递任何包属性。

你能发布你的模型代码吗?脑海中浮现的一个常见的"难题"是,在动物模型的attr_accessible上不添加package_attributes。它不会引发错误,但在SQL条目之前,您会在开发日志中看到大量分配警告。

attr_accessor不会触发回调。你必须使一个变量"脏"。点击此处了解更多信息。

在您的package.rb:中

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

这样,当它设置actual_lbs变量时,它将"弄脏"数据库中的一个变量,从而触发回调。

最新更新