Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How can I use method_source to get the source of a Rails scope? #70

Open
benlieb opened this issue Apr 25, 2021 · 2 comments
Open

How can I use method_source to get the source of a Rails scope? #70

benlieb opened this issue Apr 25, 2021 · 2 comments

Comments

@benlieb
Copy link

benlieb commented Apr 25, 2021

I have a Rails scope:

  scope :positive_amount,                    -> { where("amount > 0") }

But when I do:

Transaction.method(:positive_amount).source.display

I get:

            singleton_class.send(:define_method, name) do |*args|
              scope = all
              scope = scope._exec_scope(*args, &body)
              scope = scope.extending(extension) if extension
              scope
            end

Not the -> { where("amount > 0") } that I'd like.

Any ideas?

@ccutrer
Copy link

ccutrer commented Jul 11, 2022

this is because Rails generates a new method that will call your block only when the scope is called. method_source is properly returning the source of the generated method

@igorfokine
Copy link

igorfokine commented Dec 12, 2022

I was able to get the source code of a scope by adding this:

ActiveRecord::Scoping::Named::ClassMethods.prepend(Module.new do
  def scope(name, body, &block)
    (@__named_scopes__ ||= {})[name] = body
    super
  end
end)

Note that if you run this code in the Rails console you would need to reload the model (with default config.cache_classes, use reload! for development and Object.send(:remove_const, :Transaction); load "./app/models/transaction.rb" for production).

After that you can get the source like this:

Transaction.instance_variable_get(:@__named_scopes__)[:positive_amount].source.display

which would return

  scope :positive_amount,                    -> { where("amount > 0") }

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants