All threads / Using Named Scopes Across Models with ActiveRecord#Merge Discussion
Ask A Question


You’re not receiving notifications from this thread.

Using Named Scopes Across Models with ActiveRecord#Merge Discussion

Chris Oliver asked in General

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

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

Leung Ho Kuen ·

I am doing it with subquery


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

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

Văn Lý Vũ ·

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

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

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

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.

Ryan Johnson ·

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**.

Văn Lý Vũ ·

Nice guys.

Blake Thomson ·

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


godie mendoza ·

great! is ugly, but useful, thanks!

bodaonline ·

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

Nicholas Thompson ·

Could do something like:

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

Then you could just do:


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") }

^ would apply only green, because overwrite previous merge

Join the discussion

Want to stay up-to-date with Ruby on Rails?

Join 70,078+ developers who get early access to new tutorials, screencasts, articles, and more.

    We care about the protection of your data. Read our Privacy Policy.

    logo Created with Sketch.

    Screencast tutorials to help you learn Ruby on Rails, Javascript, Hotwire, Turbo, Stimulus.js, PostgreSQL, MySQL, Ubuntu, and more. Icons by Icons8

    © 2023 GoRails, LLC. All rights reserved.