Lets say I have two Models with a has_many-belongs_to relation. The has_many has a scope defined and an integer attribute named grade.
class Parent < ApplicationRecord
has_many :children
scope :great, -> (min_grade) {where("grade > :grade", grade: min_grade)}
end
class Child < ApplicationRecord
belongs_to :parent
end
I want to create an scope on the child model, that uses the scope of the parent model.
Is there anyhow so that I can use the definition of scope on Parent?
The way I'm doing it right now is
class Child < ApplicationRecord
belongs_to :parent
scope :wit_great_parent, -> (min_grade) {
join(:parent).where("grade > :grade", grade: min_grade)}
end
However, I'm copying the where clause in both places.
Is there anyhow to call the Parent scope from the child model?
They essentially do the same thing, the only difference is what side of the relationship you are on. If a User has a Profile , then in the User class you'd have has_one :profile and in the Profile class you'd have belongs_to :user . To determine who "has" the other object, look at where the foreign key is.
Scopes are used to assign complex ActiveRecord queries into customized methods using Ruby on Rails. Inside your models, you can define a scope as a new method that returns a lambda function for calling queries you're probably used to using inside your controllers.
Scopes are custom queries that you define inside your Rails models with the scope method. Every scope takes two arguments: A name, which you use to call this scope in your code. A lambda, which implements the query.
If you are just looking to merge in the scope then
class Child < ApplicationRecord
belongs_to :parent
scope :with_great_parent, -> (min_grade) {joins(:parent).merge(Parent.great(min_grade))}
end
should handle this for you. The SQL generated will be similar to
SELECT *
FROM children
INNER JOIN parents ON children.parent_id = parents.id
WHERE
parents.grade > --Whatever value you pass as min_grade
See ActiveRecord::SpawnMethods#merge
for more information
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