我有以下型号:
class Parcel < ActiveRecord::Base
has_one :parcel_data
# has attribute "parcel_name", which is a string
end
class ParcelData < ActiveRecord::Base
belongs_to :parcels
# has attribute "parcel_id" which is an integer
# has attribute "price" which is an integer
# has attribute "description" which is a string
end
我想选择一组Parcels
,并使用相关价格或说明。
现在,我这样做:
parcs = Parcel.where("id < ?",30)
description_array = Array.new
price_sum = 0
parcs.each do |p|
description_array.push(p.parcel_data.description)
price_sum += p.parcel_data.price
end
有没有更好的方法来构建“description_array”数组或“price_sum”值?
我知道这不起作用,但有点像:
price_sum = parcs.parcel_data.sum(:price)
description_array = parcls.parcel_data.pluck(:description)
谢谢!
答案 0 :(得分:0)
学习使用Ruby的可枚举方法将大大有助于简化像这样的代码
parcs = Parcel.where("id < ?",30)
descriptions = parcs.map {|p| p.parcel_data.description }
total_price = parcs.inject(0) {|sum, p| sum + p.parcel_data.price }
答案 1 :(得分:0)
当我喜欢点自由风格时,我会考虑:
# the Enumerable#sum used here is Rails, not Ruby
price_sum = parcels.map(&:parcel_data).compact.sum(&:price)
# plain old Ruby alternative, no Enumerable#sum
price_sum = parcels.map(&:parcel_data).compact.map(&:price).reduce(:+)
description_array = parcels.map(&:parcel_data).compact.map(&:description)
如果您的包裹没有数据,则Array#compact
:如果您的关联是强制性的,则可能不需要它。
如果您还没有加载大型数据集,可能会在控制台中节省垃圾邮件并在服务器上加载。例如,一种方式:Parcel.where("id < ?", 30).includes(:parcel_data)