I'm using Rails 5. I have the following model ...
class Order < ApplicationRecord
...
has_many :line_items, :dependent => :destroy
The LineItem model has an attribute, "discount_applied." I would like to return all orders where there are zero instances of a line item having the "discount_applied" field being not nil. How do I write such a finder method?
In Rails, you can query the database through your models to access your data. You can do this using ActiveRecord methods. Like where, find, or find_by. If you’re expecting one record (a specific user), use find_by, for multiple records (a list of users) use where.
FROM "books" WHERE "books"."id" IN (1, 2, 3) You’ll find this query in the rails logs. If you’re looking to match based on an association value, you’ll have to make that association available with the joins method. With this query you get all the books, which have a comment, and the comment id is 2.
No problem! We’re going to take a look at the different ways you can use where in your Rails applications. The purpose of using where is to build a query that filters the information in your database, so you only get the rows you want. Given a Book model, with title, author & category.
In Rails, you can query the database through your models to access your data. You can do this using ActiveRecord methods. Like where, find, or find_by. As a result you get:
First of all, this really depends on whether or not you want to use a pure Arel approach or if using SQL is fine. The former is IMO only advisable if you intend to build a library but unnecessary if you're building an app where, in reality, it's highly unlikely that you're changing your DBMS along the way (and if you do, changing a handful of manual queries will probably be the least of your troubles).
Assuming using SQL is fine, the simplest solution that should work across pretty much all databases is this:
Order.where("(SELECT COUNT(*) FROM line_items WHERE line_items.order_id = orders.id AND line_items.discount_applied IS NULL) = 0")
This should also work pretty much everywhere (and has a bit more Arel and less manual SQL):
Order.left_joins(:line_items).where(line_items: { discount_applied: nil }).group("orders.id").having("COUNT(line_items.id) = 0")
Depending on your specific DBMS (more specifically: its respective query optimizer), one or the other might be more performant.
Hope that helps.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With