从belongs_to关联

时间:2016-03-09 22:41:00

标签: ruby-on-rails ruby activerecord

我有以下型号:

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)

谢谢!

2 个答案:

答案 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 }

map documentation

inject documentation

答案 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)