Skip to content

DSL constantizes & instantiates a class on method_missing #6

@kmacdough

Description

@kmacdough

Any time an attr_reader variable names happens to line up with any defined classes (even custom user classes), the DSL eats the method_missing call and attempts to construct that class. While it might be difficult/ to avoid collisions with builtin filter/query class names, it should be possible to avoid this for unsuspecting classes.

Not familiar with this codebase yet, but it seems like this const_defined? might be the issue:
https://github.com/elastic/elasticsearch-ruby/blob/master/elasticsearch-dsl/lib/elasticsearch/dsl/search/query.rb#L28

There may be a better solution, but a class method (e.g is_elasticsearch_dsl_class?) would do the trick.

require 'elasticsearch/dsl'

class User
  def initialize(*args, **kwargs)
    puts "Initialized User with args=#{args}, kwargs=#{kwargs}"
  end
end

class MyClass
  include Elasticsearch::DSL

  attr_reader :user

  def initialize
    @user = "user_string"
  end

  def build_query_hash
    query = search do
      query do
        user_substr = user[0..5]
        match user: user_substr
      end
    end
    query.to_hash
  end
end

MyClass.new.build_query_hash

yields

Initialized User with args=[], kwargs={}
Traceback (most recent call last):
       10: from /Users/kevinmcdonough/.rvm/rubies/ruby-2.6.5/bin/irb:23:in `<main>'
        9: from /Users/kevinmcdonough/.rvm/rubies/ruby-2.6.5/bin/irb:23:in `load'
        8: from /Users/kevinmcdonough/.rvm/rubies/ruby-2.6.5/lib/ruby/gems/2.6.0/gems/irb-1.0.0/exe/irb:11:in `<top (required)>'
        7: from (irb):59
        6: from (irb):55:in `build_query_hash'
        5: from /Users/kevinmcdonough/.rvm/gems/ruby-2.6.5/gems/elasticsearch-dsl-0.1.9/lib/elasticsearch/dsl/search.rb:267:in `to_hash'
        4: from /Users/kevinmcdonough/.rvm/gems/ruby-2.6.5/gems/elasticsearch-dsl-0.1.9/lib/elasticsearch/dsl/search/query.rb:51:in `to_hash'
        3: from /Users/kevinmcdonough/.rvm/gems/ruby-2.6.5/gems/elasticsearch-dsl-0.1.9/lib/elasticsearch/dsl/search/query.rb:42:in `call'
        2: from /Users/kevinmcdonough/.rvm/gems/ruby-2.6.5/gems/elasticsearch-dsl-0.1.9/lib/elasticsearch/dsl/search/query.rb:42:in `instance_eval'
        1: from (irb):51:in `block (2 levels) in build_query_hash'
NoMethodError (undefined method `[]' for #<User:0x00007ff983854308>)

EDIT: cleaned up language to be clearer.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions