Skip to content

Access IssuesFinder::Params explicitly to get correct constant

Mehmet Emin INAC requested to merge fix_no_method_error_for_issuable_finder into master

What does this MR do?

There is a really interesting issue that is causing because of the way Ruby resolves the constants(default behavior) and the load orders only on the local environment because of the lazy load feature of Rails.

Diagnosis

Ruby loads the constants with const_get method defined for the singleton object of Module here. This method tries to access a constant defined for a module and it has a parameter called inherit which is true by default which lets the VM to load the constant from the ancestors of a module in case if it's missing for the module itself.

Which means, if we define a class called A which is inherited from another class called B and a constant called C within the namespace of A in a separate file, in case if we try to access A::C;

  1. VM will try to find the constant defined under A but can't find because the file which defines C under A is not loaded yet
  2. VM will try to find the constant defined under B because the inherit flag is set as true by default. If it finds the constant then it will return it, if not, it goes to step 3
  3. After checking all the ancestors, VM calls the const_missing method which can be handled by libraries like Active Support to load the correct file which may define the missing constant.

Based on this, setting the inherit flag as false while accessing the constant will let Active Support to load the correct constant which solves the issue.

Another solution would be just adding require_dependency 'issues_finder/params' right after opening the class definition of IssuesFinder.

An example to test this behavior locally with plain Ruby;

class IssuableFinder
  def params_class
  end

  class Params
  end
end


class IssuesFinder < IssuableFinder
  def params_class
    IssuesFinder::Params # Notice the const name!
  end
end

IssuableFinder::Params

puts IssuesFinder.new.params_class # IssuableFinder::Params

Test with Gitlab Rails console;

IssuableFinder::Params
user = User.last
IssuesFinder.new(user, assignee_id: user.id).params_class # => IssuableFinder::Params

Screenshots

Does this MR meet the acceptance criteria?

Conformity

Availability and Testing

Security

If this MR contains changes to processing or storing of credentials or tokens, authorization and authentication methods and other items described in the security review guidelines:

  • [-] Label as security and @ mention @gitlab-com/gl-security/appsec
  • [-] The MR includes necessary changes to maintain consistency between UI, API, email, or other methods
  • [-] Security reports checked/validated by a reviewer from the AppSec team
Edited by Mehmet Emin INAC

Merge request reports