Question

This is a question from a rails noob trying to understand concerns and scopes.

I always thought scopes were class methods in rails but then the other day I saw this code from DHH:

module Visible
  extend ActiveSupport::Concern`

  module ClassMethods
    def visible_to(person)
      where \
        "(#{table_name}.bucket_id IN (?) AND
          #{table_name}.bucket_type = 'Project') OR
         (#{table_name}.bucket_id IN (?) AND
          #{table_name}.bucket_type = 'Calendar')",
        person.projects.pluck('projects.id'), 
        calendar_scope.pluck('calendars.id')
    end
  end
end

So the way the visible method is used is like so:

current_account.posts.visible_to(current_user)

This is what is confusing me. Self here is a collection of posts so we are acting on instances whereas the visible method seems to be meant to be used as a class method. Isn't david trying to call a class method as a dynamic scope? Could someone please clarify?

Was it helpful?

Solution

Class methods on classes which inherit ActiveRecord::Base can be used also as scopes (on ActiveRecord Relation objects).

Since the module Visible was meant to be mixed into a model which inherits ActiveRecord::Base, its class method visible_to can be used also as a scope.

If this did not clear the issue, you can implement a scope which gets all adult users (age > 20) in the following ways:

class User < ActiveRecord::Base
  scope :adult, lambda { where("age > ?", 20) } # with a scope

  class << self
    def adult # with class method
      where("age > ?", 20)
    end
  end
end

And use it exactly the same with User.adult

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top