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

Fix NoMethodError at Orthoses::ActiveRecord::Scope middleware #18

Merged
merged 2 commits into from
Nov 5, 2023

Conversation

sanfrecce-osaka
Copy link
Contributor

When passing callable object to scope

e.g. using Query Object Pattern
c.f. https://takaokouji.github.io/output/query-object/

class FilterByStatusQuery
  private attr_reader :relation, :options

  def self.call(*args)
    new(*args).send(:query)
  end

  def initialize(*args)
    @options = args.extract_options!
    @relation = Blog
  end

  private

  def query
    relation.where(status: options[:status])
  end
end

class Blog < ApplicationRecord
  scope :by_status, FilterByStatusQuery
end

Orthoses raises NoMethodError because Class doesn't respond to parameters

$ bin/rails orthoses:rails

...

Caused by:
NoMethodError: undefined method `parameters' for FilterByStatusQuery:Class (NoMethodError)

          definition = "#{name}: #{parameters_to_type(body.parameters)} -> #{base_name}::ActiveRecord_Relation"
                                                          ^^^^^^^^^^^

So captured argument body is not Proc and callable, we should use Method#parameters

When passing callable object to scope

e.g. using Query Object Pattern
c.f. https://takaokouji.github.io/output/query-object/

```ruby
class FilterByStatusQuery
  private attr_reader :relation, :options

  def self.call(*args)
    new(*args).send(:query)
  end

  def initialize(*args)
    @options = args.extract_options!
    @relation = Blog
  end

  private

  def query
    relation.where(status: options[:status])
  end
end

class Blog < ApplicationRecord
  scope :by_status, FilterByStatusQuery
end
```

Orthoses raises NoMethodError because Class doesn't respond to parameters

```
$ bin/rails orthoses:rails

...

Caused by:
NoMethodError: undefined method `parameters' for FilterByStatusQuery:Class (NoMethodError)

          definition = "#{name}: #{parameters_to_type(body.parameters)} -> #{base_name}::ActiveRecord_Relation"
                                                          ^^^^^^^^^^^
```

So captured argument body is not Proc and callable, we should use Method#parameters
Copy link
Owner

@ksss ksss left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you for reporting. I did't know that pattern.

lib/orthoses/active_record/scope.rb Outdated Show resolved Hide resolved
c.f. https://github.com/ksss/orthoses-rails/pull/18/files#r1382400198

> In Rails, it seems to branch based on the presence of `#to_proc`. Also, since the `#call` presence is checked by the `#scope`, it seems unnecessary to check for `#call` here. Therefore, how about making the following correction?
> 
> ref: https://github.com/rails/rails/blob/8c82595b8c862eb087615a14f61ded528274eeae/activerecord/lib/active_record/scoping/named.rb#L173-L185

Co-authored-by: Yuki Kurihara <co000ri@gmail.com>
Copy link
Owner

@ksss ksss left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍

@ksss ksss merged commit dcb856e into ksss:main Nov 5, 2023
ksss added a commit that referenced this pull request Nov 5, 2023
@ksss
Copy link
Owner

ksss commented Nov 5, 2023

@sanfrecce-osaka I released v1.4.0.
Please check it out!

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

Successfully merging this pull request may close these issues.

2 participants