如何基于此对象数据创建实例方法?

时间:2011-08-18 14:55:38

标签: ruby-on-rails ruby ruby-on-rails-3

我在这个变量中有一些数据,我想知道如何编写一个方法来给我项目价格的总和。

模型名称及其关联:

Order
- belongs_to :customer
- has_many :item_orders
- has_many :items, :through => :item_orders
- accepts_nested_attributes_for :item_orders, :allow_destroy => true, :reject_if => lambda { |a| a['item_id'].blank? }


Item
- has_many :item_orders, :dependent => :destroy
- has_many :orders, :through => :item_orders
- accepts_nested_attributes_for :item_orders, :allow_destroy => true

ItemOrder
- belongs_to :item
- belongs_to :order

做的:

<%= debug @order.items %> 

# returns me

- !ruby/object:Item
  attributes:
  id: 31
  title: Golden Ring 2
  price: 13445.0
  labour_cost: 500.0
  item_type_id: 10
  created_at: 2011-08-13 10:53:24.000000000Z
  updated_at: 2011-08-18 06:10:36.000000000Z
  photo: golden_ring.jpg
  changed_attributes: {}
  previously_changed: {}
  attributes_cache: {}
  marked_for_destruction: false
  destroyed: false
  readonly: false
  new_record: false
- !ruby/object:Item
 attributes:
  id: 32
  title: Special Pendant
  price: 171.67
  labour_cost: 120.0
  item_type_id: 20
  created_at: 2011-08-13 11:09:43.000000000Z
  updated_at: 2011-08-14 06:03:02.000000000Z
  photo: prd_194_48cd9b21771dd.jpg
  changed_attributes: {}
  previously_changed: {}
  attributes_cache: {}
  marked_for_destruction: false
  destroyed: false
  readonly: false
  new_record: false

所以,我想在Order模型类中编写一个方法,以便在视图上进行类似的写操作。

 <%= @order.items.total_price %>

total_price方法将对所有商品价格求和,并乘以@order.items中包含的数量。

我的疑问是:从方法内部,我怎样才能访问items集合来执行求和操作。

def total_price
  self.item_order.each do |i| { 
     result += i.quantity * i.items.price
  }
end

编辑:我完全忘了提及我必须考虑数量才能使这个数学。

6 个答案:

答案 0 :(得分:2)

在order.rb中定义一个函数,如下所示:

def total_price
  self.items.inject(0) {|sum, item| sum + item.price }
end

在视图中:

<%= @order.total_price %>

答案 1 :(得分:1)

<%= @order.items.inject(0) {|sum, item| sum + item.price} %>

答案 2 :(得分:1)

如果订单模型中有has_many :items,您应该可以轻松使用变量。您需要做的就是在订单模型中写下:

def total_price
  items.to_a.sum {|item| item.price}
end

答案 3 :(得分:1)

您有两种可能的方法。

1)使用ActiveRecord sum。这是有效的,因为在DB中执行SUM操作。当您处理100行时,这是要走的路:

items.sum(:price)  # executes select sum(items.price) 
                   #          from items where items.order_id = some_id

2)使用枚举sum。在这里,您正在使用现有阵列。

items.to_a.sum(&:price)

当我的has_many association列表大小很小(<10)且已经急切加载时,我使用这种方法。

修改1:根据其他要求

使用ActiveRecord:

item_orders.sum("item_orders.quantity * item.price", :join => :item)

使用枚举

item_orders.all(:include => :item).sum {|io| io.quantity * io.item.price }

答案 4 :(得分:0)

我很确定你可以这么做;

def total_price
  items.sum(:price)
end

答案 5 :(得分:0)

解决。

在我的order.rb我创建了total_price方法。

def total_price
  self.item_orders.to_a.sum { |item| item.full_price }
end

然后,在我的item_order.rb

def full_price
  quantity * self.item.price
end

这就是我需要的。谢谢大家!