Неопределенный метод NoMethodError `[]=' для nil:NilClass

Я создал несколько классов с одним тестовым методом, чтобы проверить правильность сериализации рубиновых объектов.

Ошибка вернулась:

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

Я запускаю приведенный ниже метод test_query через консоль rails, инициализируя QueryModelTester, а затем вызывая метод test_query() для этого объекта.

Мой код:

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

Вот классы моделей, которые тестирует вышеуказанный класс:

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

person Horse Voice    schedule 15.07.2015    source источник
comment
Опубликуйте query_model.rb содержание   -  person RAJ    schedule 15.07.2015


Ответы (1)


Проблема в том, что когда вы инициализируете файл @query_hash. Во всех ваших классах они инициализируются в неправильной области. Чтобы исправить это, вы должны переместить метод @query_hash = Hash.new в initialize, например:

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

Надеюсь, это поможет.

Удачи!

person Paweł Dawczak    schedule 15.07.2015
comment
Спасибо. Хотя не уверен, что полностью понимаю. Что, если бы я не использовал конструктор в классе, как/где бы я определил query_hash, чтобы это работало? Могу ли я использовать родительский класс и просто определить его там один раз, и все классы наследуют его, или я не могу сделать его переменной экземпляра? Пожалуйста, проясните некоторые из этих сомнений, которые у меня есть. Благодарю вас! - person Horse Voice; 15.07.2015
comment
@HorseVoice, да - вы можете использовать один родительский класс, от которого другие могут наследоваться, и сохранить там инициализацию @query_hash. Насколько это сработает, я недостаточно знаю ваш код, чтобы рекомендовать этот конкретный подход. Использование наследования только для уменьшения объема кода — не лучшая идея, но если все эти классы кажутся подтипами, это может быть хорошим выбором. Не уверен, что это проясняет или вызывает больше вопросов (архитектура программного обеспечения непростая), но с ограниченными знаниями о вашей системе это единственный ответ. С Уважением! - person Paweł Dawczak; 15.07.2015