0

I created multiple classes with one test method to test wither the ruby objects get serialized correctly.

The error returned:

undefined method `[]=' for nil:NilClass
    from /Users/horse/workspace/queryapi/app/models/query_model.rb:193:in `serialize'

I run the below test_query method through the rails console by initializing QueryModelTester and then invoking test_query() method on that object.

My code:

class QueryModelTester
  def test_query
    must = Must.new
    range_criteria = RangeCriteria.new 
    range_criteria.gte = 20140712
    range_criteria.lte = 1405134711

    range = RangeBuilder.new
    range.search_field = "created_time"
    range.range_criteria = range_criteria

    must.range = range
    bool = Bool.new
    bool.must = must

    main_query = bool.serialize
    puts main_query
  end
end

Here are the model classes the above class is testing:

class RangeCriteria    
  @query_hash = Hash.new
  attr_accessor :gte, :lte

  def serialize
    if(@gte.present?)
      @query_hash[:gte] = @gte
    end

    if(@lte.present?)
      @query_hash[:lte] = @lte
    end

    if(@gte.present? || @lte.present?) 
      return @query_hash
    end
  end
end


class RangeBuilder
  @query_hash = Hash.new
  attr_accessor :search_field, :range_criteria

  def serialize
    if(@search_field.present?)
      @query_hash[@search_field] = @range_criteria.serialize
      return @query_hash[:range] = @query_hash
    end
  end    
end

class Bool
  @query_hash = {}
  attr_accessor :must

  def serialize
    if( @must.present? )
      @query_hash[:must] = @must.serialize
      return @query_hash[:bool] = @query_hash
    end
  end
end
wurde
  • 2,487
  • 2
  • 20
  • 39
Horse Voice
  • 8,138
  • 15
  • 69
  • 120

1 Answers1

1

The problem is when you initialize your @query_hash. In all your classes they are initialized in wrong scope. To fix it, you should move @query_hash = Hash.new to initialize method, like:

class RangeCriteria
  def initialize
    @query_hash = Hash.new
  end
    # ...
end

class RangeBuilder
  def initialize
    @query_hash = Hash.new
  end
    # ...
end

class Bool
  def initialize
    @query_hash = Hash.new
  end
    # ...
end

Hope that helps.

Good luck!

Paweł Dawczak
  • 9,519
  • 2
  • 24
  • 37
  • Thank you. Not sure if I understand completely though. What if I didnt use a constructor in the class, how/where would I define query_hash so that this works? Could I use a parent class and just define it once in there and all the classes inherit it or can I not make it an instance variable? Please clarify some of these doubts i have. Thank you! – Horse Voice Jul 15 '15 at 10:09
  • @HorseVoice, yes - you can go with a single parent class that others can inherit from, and keep the `@query_hash` initialization there. As far as it would work, I don't know enough about your code to advise this particular approach. Using inheritance *only for decreasing amount of code* is not the best idea, but if all of these classes seem to be a subtype, this might be a good choice. Not sure if this clarifies or produces more questions (software architecture is not easy), but with limited knowledge about your system this is the only answer. Regards! – Paweł Dawczak Jul 15 '15 at 10:19