Skip to main content

Using Named Scopes Across Models with ActiveRecord#Merge Discussion

General • Asked by Chris Oliver
17627efb3af54120f7eb96e7d6eb843e

You have to fix your latest blog Post excerpt on the home page.
Great site btw.

Ce795239ba5dd2384fc2f88ffaff5451

Doh! I'll get on that. My markdown parser sure didn't like that video.


4f873fd56f2bb58c0a13847a46b481f3

I am doing it with subquery
Like

Author.where(id: Book.available.select(:author_id))

I agree that your version is cleaner and easier to remember,
but you might want to add .distinct after joins to avoid duplicated authors.

Ce795239ba5dd2384fc2f88ffaff5451

Ah yes, great points! I like that as a subquery and definitely need the distinct for my example as well.

225b99d20b9c26a3109309fb129aacd5

this query will generate a long SQL query. it's not best practice.


31c303231b0ebf57813f0b73dafbc7fd

Well, this is useful, but ugly... Thinking about querying, im not supposed to "merge" anything. IMHO

My wish was Author.books.scope(:available), lol

Ce795239ba5dd2384fc2f88ffaff5451

Well you can do Author.books.available because that's just querying Book.where(author_id: X).available. But obviously this is for the more complex joining tables case, so at least you're working with the models like you normally would. Not the best, but it saves you from duplication.

00405645c5fe2805e62c31576cf8cebc

The difference is that Author.books.available will return books, but Author.joins(:books).merge(Book.available) will return authors. Using merge is useful when your desired record set has conditions that are dependant on another table. As stated in the video, you're looking for **Authors** with available books, not available **books**.

225b99d20b9c26a3109309fb129aacd5

Nice guys.


87bdc8a941586891446e2cc46682de32

Minor nitpick: but I really think you mean `ActiveRecord::Relation#merge`, not `ActiveRecord#merge`


272f9887406e6bebd6120d113e755afb

8633ff48039df22fb15f1df0cf91e91d

Aacb3884349bed64e010f6419890b211

great! is ugly, but useful, thanks!


D250c8a4f37d4d8b284122047c81985c

Big thanks! Had a default scope on my Model but rails 4.2.5 didn't unscope it when I was doing "each do" so using the .joins(:model).merge(Model.scope) you suggested instead


870ccdb57016c46120bb8e93f8bca94a

Could do something like:

scope :has_available_books, -> { joins(:books).merge(Book.available) }

Then you could just do:

Author.has_available_books


9825be25f35a1eb7d13a873b661709f2
Konstantin Ivanov

Need to note that merges on the same attribute overrides each other.

class Book < ActiveRecord::Base
...
scope :red, ->{ where(color: "red") }
scope :green, ->{ where(color: "green") }
end

Author.joins(:books).merge(Book.red).merge(Book.green)
^ would apply only green, because overwrite previous merge


Login or Create An Account to join the conversation.

Subscribe to the newsletter

Join 18,000+ developers who get early access to new screencasts, articles, guides, updates, and more.

By clicking this button, you agree to the GoRails Terms of Service and Privacy Policy.

More of a social being? We're also on Twitter and YouTube.