我有一个名为@jdc_array
的实例变量,在检查时其内容如下所示:
"[#<ActiveRecord::Associations::CollectionProxy [#<JobDeliveryCost id: 13, job_id: 53, delivery_cost_id: 1, cost_per_unit: 50.0, quantity: 3, timing: \"install\", created_at: \"2014-07-23 15:20:34\", updated_at: \"2014-07-23 15:20:34\">, #<JobDeliveryCost id: 15, job_id: 53, delivery_cost_id: 1, cost_per_unit: 50.0, quantity: 5, timing: \"install\", created_at: \"2014-07-23 15:57:45\", updated_at: \"2014-07-23 15:57:45\">, #<JobDeliveryCost id: 18, job_id: 53, delivery_cost_id: 1, cost_per_unit: 44.0, quantity: 1, timing: \"breakdown\", created_at: \"2014-07-23 18:27:20\", updated_at: \"2014-07-23 18:27:20\">, #<JobDeliveryCost id: 19, job_id: 53, delivery_cost_id: 1, cost_per_unit: 22.0, quantity: 1, timing: \"install\", created_at: \"2014-07-23 18:27:28\", updated_at: \"2014-07-23 18:27:28\">, #<JobDeliveryCost id: 20, job_id: 53, delivery_cost_id: 1, cost_per_unit: 3.0, quantity: 1, timing: \"install\", created_at: \"2014-07-23 18:28:45\", updated_at: \"2014-07-23 18:28:45\">]>, nil]"
我想总结cost_per_unit:
的所有实例,所以我创建了这个方法
def calculate_delivery_total(array)
array.map(&:cost_per_unit).inject(0, &:+)
end
并像这样调用方法:
def index
if get_deliverable
@jdc_array=(@job.job_delivery_costs.any? ? [@job.job_delivery_costs,@new_delivery] : [@new_delivery])
@new_delivery = @deliverable.job_delivery_costs.build
end
set_job_delivery_cost
@total = calculate_delivery_total(@jdc_array)
end
但是我发现这个错误!?!
formal argument cannot be an instance variable def calculate_delivery_total(@array)
三个问题。为什么我会收到此错误,如何解决?第三,在控制器中做这样的事情是好的形式,还是我应该在其他地方做这些以及如何做?
更新
所以按照SO海报的建议我将方法改为
def calculate_delivery_total(array)
array.map(&:cost_per_unit).inject(0, &:+)
end
但我仍然收到此错误
undefined method `cost_per_unit' for #<ActiveRecord::Associations::CollectionProxy::ActiveRecord_Associations_CollectionProxy_JobDeliveryCost:0x00000106172788>
我可以在控制台中执行此操作,为什么不在这里工作?!
答案 0 :(得分:0)
要回答第二个问题,我使用外观模式为视图准备数据。这样可以避免在视图或控制器中进行计算,并促进关注点和重用的分离。
这是一个资源,但我可以在编辑中进行扩展。
https://medium.com/@ryakh/facade-pattern-on-rails-d65b86cdb5b1
对于错误,它是一个猜测,但可能是数组的最后一个元素是零吗?你试过.to_a和紧凑型吗?
def calculate_delivery_total(array)
array.to_a.compact.map(&:cost_per_unit).inject(0, &:+)
end
答案 1 :(得分:0)
您的@jdc_array
可以是以下两个值之一:
[@job.job_delivery_costs,@new_delivery]
或者
[@new_delivery]
我不知道@new_delivery
是什么,但job_delivery_costs
会返回JobDeliveryCost
的集合(更具体地说是CollectionProxy
)对象,这意味着你在集合中有一个集合。
另一方面,@new_delivery
可能是nil
(根据帖子开头的示例数据),可能是因为在您之后为其分配了一个值。把它放在数组(数组中的值不会改变) - 你需要交换这些行。
我的建议是更改方法以接收两个参数 - 交付成本列表和新交付,如下所示:
def calculate_delivery_total(deliveries, new_delivery)
total = 0
unless deliveries.nil?
total = deliveries.map(&:cost_per_unit)
end
unless new_delivery.nil?
total += new_delivery.cost_per_unit
end
total
end
并且您的index
代码应该如下所示:
def index
if get_deliverable
@new_delivery = @deliverable.job_delivery_costs.build
end
set_job_delivery_cost
@total = calculate_delivery_total(@job.job_delivery_costs,@new_delivery)
end