如何在Ruby循环外部获取计算值?代码实现疑问求助
解决方案:把价格计算逻辑抽成可复用方法或收集明细数据
这个问题我之前重构代码时也碰到过——块里面的变量确实是作用域受限的,没法直接拿到外面用。咱们可以通过两种方式来实现你想要的效果:
方案一:封装单个商品项的价格计算方法
把原来写在sum块里的判断和计算逻辑抽成一个独立的方法,这样不管是在求和循环里还是外部单独计算某个商品的价格,都能直接调用:
# 可以放在你的控制器、模型或者辅助模块里 def calculate_line_item_price(line_item) shop_product = line_item.shop_product # 先抽取出打印位置的总价,避免重复计算 print_locations_total = shop_product.print_locations.sum(&:vendor_price) vendor_product = shop_product.product.vendor_product # 根据method类型计算最终价格 if shop_product.method_1? print_locations_total + vendor_product.price_method_1 elsif shop_product.method_2? print_locations_total + vendor_product.price_method_2 else 0 # 这里可以根据业务需求设置默认值,比如抛出异常或者返回0 end end
然后原来的求和代码就可以简化成:
# 计算总价 total_price = @order.cart.line_items.sum { |li| calculate_line_item_price(li) } # 外部单独获取某个商品项的价格也很方便 single_line_item = @order.cart.line_items.first item_price = calculate_line_item_price(single_line_item)
方案二:收集每个商品项的详细价格数据
如果需要同时保留method_1_price和method_2_price的明细(而不是直接求和),可以用map把每个商品项的价格数据收集成数组,之后在外部随便用:
# 收集所有商品项的价格明细 price_details = @order.cart.line_items.map do |li| shop_product = li.shop_product print_total = shop_product.print_locations.sum(&:vendor_price) vendor_product = shop_product.product.vendor_product # 分别计算两种方法的价格(只有对应method激活时才赋值,否则为0) method1_price = shop_product.method_1? ? (print_total + vendor_product.price_method_1) : 0 method2_price = shop_product.method_2? ? (print_total + vendor_product.price_method_2) : 0 # 把数据存成哈希,方便后续访问 { line_item: li, method_1_price: method1_price, method_2_price: method2_price, total: method1_price + method2_price } end # 计算所有商品的总价 total_price = price_details.sum { |detail| detail[:total] } # 外部可以随便访问每个商品的method价格,比如第一个商品的method_1_price first_item_method1_price = price_details.first[:method_1_price]
这样不管是想单独拿某个商品的价格明细,还是整体求和,都能轻松实现,代码也比原来的嵌套块清晰多了。
内容的提问来源于stack exchange,提问作者uno
相关产品推荐
相关产品推荐

