I have a concern that adds a scope to ActiveRecord classes that include it. Most of the time its fine the way it is but depending on the class there might extra criteria that needs to be met. I don't want to have to rewrite the scope in the model but be able to just add on an extra criteria method.
Here's what I'm trying to do:
module MyConcern
extend ActiveSupport::Concern
included do
# I've included the fact I pass a limit variable here because my scope also does this, in case that's relevant for solving this.
# I'd like this to be private or not accessible via `MyModel._my_scope`
scope :_my_scope, ->(limit = nil) { (joins, wheres, order etc etc).limit(limit) }
scope :my_scope, ->(limit = nil) { _my_scope(limit) }
end
end
class MyModel < ApplicationRecord
include MyConcern
# Including the "private" scope to add my extra criteria.
scope :my_scope, ->(limit = nil) { _my_scope(limit).where(foo: 'bar') }
end
class AnotherModel < ApplicationRecord
include MyConcern
# I like the default behavior here so nothing else to do
end
This works but from outside the class you can do this: MyModel._my_scope which I guess is ok - maybe theres a time when I'd want the default behavior - but in this case I dont think I do and I feel like encapsulating _my_scope is the way to go.
I'm assuming it's possible to make a private class method in MyConcern that gets included in MyModel but that doesn't seem to work and I'm not really a Concern/mixin master yet so not sure how to go about doing this. Also, are Concerns considered to be mixins? Is there a difference? That would be good to know also.
You can achieve the same functionality of scopes with class methods, that you can inherit and extend for this case. It's not much different than your implementation; just avoids the use of the extra _ method by using a class method instead of a scope. E.g.
For the second part of your question: A concern is technically a ruby Mixin; it's just a convention to organize/group the Mixins that are included in your Models only as concerns. Using ActiveSupport::Concern allows you to add additional Model related functionality to your Mixins like scope, validations etc. which you can't get using a normal Module. E.g. You can't do