如何通过has_many关联操作ActiveRecord Relation?解决调用报错问题
ActiveRecord关联查询问题解决
报错原因
included_ice_cream是IceCream::ActiveRecord_Relation(IceCream的集合对象),而ontario_sales_receipts是单个IceCream实例才有的关联方法,直接在集合上调用会触发undefined method错误。
两种可行解决方案
方案1:从IceCream出发,高效关联计算
不用先查询IceCream集合再调用关联,直接通过joins关联销售记录并聚合计算,减少内存占用:
final_amount = IceCream.produced_this_or_previous_month .where(low_fat: true, expired: false) .joins(:ontario_sales_receipts) .sum('ontario_sales_receipts.number_of_buckets') * BUCKET_PRICE
如果需要保留IceCream集合,也可以用flat_map(注意:数据量大时会加载所有关联对象,效率较低):
included_ice_cream = IceCream.produced_this_or_previous_month.where(low_fat: true, expired: false) final_amount = included_ice_cream.flat_map(&:ontario_sales_receipts).sum(&:number_of_buckets) * BUCKET_PRICE
方案2:直接从OntarioSalesReceipt反向查询
通过joins关联IceCream表,在where中指定IceCream的筛选条件,还可以用merge复用已有的scope:
# 查询符合条件的安省销售记录 included_ontario_sales_receipts = OntarioSalesReceipt.joins(:ice_cream) .where( ice_cream: { low_fat: true, expired: false } ) .merge(IceCream.produced_this_or_previous_month) # 计算总销售额 final_amount = included_ontario_sales_receipts.sum(:number_of_buckets) * BUCKET_PRICE
内容的提问来源于stack exchange,提问作者daveasdf_2
相关产品推荐
相关产品推荐

