简体   繁体   中英

How To Sum Column In Relation with active record rails

I have question about summing 2 columns in a relation, with records such as:

#<RequestProduct id: 26, request_id: 27, product_service_id: 9, quantity: 12, created_at: "2015-09-12 04:58:19", updated_at: "2015-09-12 04:58:19">,
#<RequestProduct id: 27, request_id: 27, product_service_id: 10, quantity: 11, created_at: "2015-09-12 04:58:19", updated_at: "2015-09-12 04:58:19">,
#<RequestProduct id: 28, request_id: 27, product_service_id: 11, quantity: 10, created_at: "2015-09-12 04:58:20", updated_at: "2015-09-12 04:58:20">

I want to sum quantity on model RequestProduct with price in model ProductService. I've tried to use some ways but still failed, the way that I use like this:

@request.request_products.sum("quantity * request_products.product_service.price")
@request.request_products.sum("quantity * product_service.price")
@request.request_products.sum("quantity * ?", product_service.price)

Is there any other way?

You need to try something like this:

res = @request.request_products.joins(:product_services)
        .select("sum(request_products.quantity) as quantities, sum(product_services.price * request_products.quantity) as total")

Now you can access sum values via:

res.quantities # total quantity
res.total      # total amount

One method, which makes this rather invisible to Rails, is to define a view in the database to join the tables, perform the arithmetic, and maybe even aggregate the numbers.

By exposing the appropriate key id columns of the underlying table and creating a model for the view (mark it as readonly), you can treat it as a regular Rails model with all of the complexity pushed down into the database layer.

Some developers will hate this, as it could be argued that it moves business logic into the the database layer, which they're not comfortable with. Also, just using this to simply join tables and multiply values may not be a strong enough use case, and the arguments in favour may get stronger if you did need to aggregate.

However it's not complex logic, and simplicity in the Rails level and performance of the system, would probably be unmatched by any other method.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM