rs-pro / mongoid-elasticsearch

DEPRECATED - Consider using SearchKick https://github.com/ankane/searchkick
MIT License
61 stars 23 forks source link

results throws Mongoid::Errors::UnknownAttribute #16

Open asgerb opened 9 years ago

asgerb commented 9 years ago

I have a Page model that embeds_many WebModules:

class Page
  include Mongoid::Document
  include Mongoid::Elasticsearch
  elasticsearch!

  embeds_many :web_modules, cascade_callbacks: true

end

When I run Page.es.search(params[:q]) there's no problem. But when trying to get the results: Page.es.search(params[:q]).results it throws a Mongoid::Errors::UnknownAttribute error:

Mongoid::Errors::UnknownAttribute - 
Problem:
  Attempted to set a value for 'align' which is not allowed on the model WebModule.
Summary:
  Without including Mongoid::Attributes::Dynamic in your model and the attribute does not already exist in the attributes hash, attempting to call WebModule#align= for it is not allowed. This is also triggered by passing the attribute to any method that accepts an attributes hash, and is raised instead of getting a NoMethodError.

raw_response works fine though.

It seems to be a problem of the embedded web_modules, but I'm not sure. mongoid_elasticsearch doesn't actually try to write to the documents right?

james-ai commented 9 years ago

I'm seeing this error too.

I have two classes: Article, and Preview. Preview subclasses Article but specifies that it belongs to a Fixture. Articles do not belong to a Fixture.

class Preview < Article
  belongs_to :fixture
end

When I run Article.es.search('Fulham').results it throws the Mongoid::Errors::UnknownAttribute error:

Mongoid::Errors::UnknownAttribute: 
Problem:
  Attempted to set a value for 'fixture_id' which is not allowed on the model Article.
Summary:
  Without including Mongoid::Attributes::Dynamic in your model and the attribute does not already exist in the attributes hash, attempting to call Article#fixture_id= for it is not allowed. This is also triggered by passing the attribute to any method that accepts an attributes hash, and is raised instead of getting a NoMethodError.
Resolution:
  You can include Mongoid::Attributes::Dynamic if you expect to be writing values for undefined fields often.
    from /Users/jamessmith/.rvm/gems/ruby-2.1.2/gems/mongoid-4.0.1/lib/mongoid/attributes/processing.rb:96:in `process_attribute'
    from /Users/jamessmith/.rvm/gems/ruby-2.1.2/gems/mongoid-4.0.1/lib/mongoid/attributes/processing.rb:25:in `block in process_attributes'
    from /Users/jamessmith/.rvm/gems/ruby-2.1.2/gems/mongoid-4.0.1/lib/mongoid/attributes/processing.rb:23:in `each_pair'
    from /Users/jamessmith/.rvm/gems/ruby-2.1.2/gems/mongoid-4.0.1/lib/mongoid/attributes/processing.rb:23:in `process_attributes'
    from /Users/jamessmith/.rvm/gems/ruby-2.1.2/gems/mongoid-4.0.1/lib/mongoid/document.rb:110:in `block in initialize'
    from /Users/jamessmith/.rvm/gems/ruby-2.1.2/gems/mongoid-4.0.1/lib/mongoid/threaded/lifecycle.rb:84:in `_building'
    from /Users/jamessmith/.rvm/gems/ruby-2.1.2/gems/mongoid-4.0.1/lib/mongoid/document.rb:104:in `initialize'
    from /Users/jamessmith/.rvm/gems/ruby-2.1.2/gems/mongoid-elasticsearch-0.8.3/lib/mongoid/elasticsearch/response.rb:185:in `new'
    from /Users/jamessmith/.rvm/gems/ruby-2.1.2/gems/mongoid-elasticsearch-0.8.3/lib/mongoid/elasticsearch/response.rb:185:in `rescue in block in multi_without_load'
    from /Users/jamessmith/.rvm/gems/ruby-2.1.2/gems/mongoid-elasticsearch-0.8.3/lib/mongoid/elasticsearch/response.rb:174:in `block in multi_without_load'
    from /Users/jamessmith/.rvm/gems/ruby-2.1.2/gems/mongoid-elasticsearch-0.8.3/lib/mongoid/elasticsearch/response.rb:157:in `map'
    from /Users/jamessmith/.rvm/gems/ruby-2.1.2/gems/mongoid-elasticsearch-0.8.3/lib/mongoid/elasticsearch/response.rb:157:in `multi_without_load'
    from /Users/jamessmith/.rvm/gems/ruby-2.1.2/gems/mongoid-elasticsearch-0.8.3/lib/mongoid/elasticsearch/response.rb:78:in `results'
    from (irb):10
    from /Users/jamessmith/.rvm/gems/ruby-2.1.2/gems/railties-4.2.0/lib/rails/commands/console.rb:110:in `start'
    from /Users/jamessmith/.rvm/gems/ruby-2.1.2/gems/railties-4.2.0/lib/rails/commands/console.rb:9:in `start'
    from /Users/jamessmith/.rvm/gems/ruby-2.1.2/gems/railties-4.2.0/lib/rails/commands/commands_tasks.rb:68:in `console'
    from /Users/jamessmith/.rvm/gems/ruby-2.1.2/gems/railties-4.2.0/lib/rails/commands/commands_tasks.rb:39:in `run_command!'
    from /Users/jamessmith/.rvm/gems/ruby-2.1.2/gems/railties-4.2.0/lib/rails/commands.rb:17:in `<top (required)>'
    from bin/rails:4:in `require'
    from bin/rails:4:in `<main>'2.1.2 :011 >

However, when I run Preview.es.search('Fulham').results I get no such error.

The log message suggests this is being generated by https://github.com/rs-pro/mongoid-elasticsearch/blob/master/lib/mongoid/elasticsearch/response.rb#L185

begin
  m = klass.new(h.merge(source))
  if defined?(Moped::BSON)
    m.id = Moped::BSON::ObjectId.from_string(h['_id']) 
  else
    m.id = BSON::ObjectId.from_string(h['_id'])
  end
rescue Mongoid::Errors::UnknownAttribute
   klass.class_eval <<-RUBY, __FILE__, __LINE__+1
     attr_accessor :_type, :_score, :_source, :_highlight
   RUBY
   m = klass.new(h.merge(source)) # <--- I guess it fails here?
end

Any thoughts?

dfabreguette commented 8 years ago

I have same issue, from what I understand, problem is elasticsearch indexed data does not fit mongodb data and mongoid does not allow elasticsearch gem from creating the object and adding extra attributes dynamically to mongodb...

My question is, when I ran into this, I used MyModel.es.index_all from rails console but it didn't change anything, any idea ??

dfabreguette commented 8 years ago

Actually it was all my fault. For anyone having same issue, My problem was I had some data in my mongodb with a specific field that wasn't declared anymore in my model (as it was deprecated) but Elasticsearch was still indexing it ... Solution was to remove the field from mongodb (using unset method) and reindexing my model using "MyModel.index_all".

shahfaizanali commented 8 years ago

@dfabreguette-ap I am using mongoid-slug and I get same error Attempted to set a value for 'slug' which is not allowed on the model. Any thoughts how I can get rid of it.

dfabreguette commented 8 years ago

@shahfaizanali Probably same problem. Did you add the mongoid slug feature on a model once and removed it afterward ? If so, just unset the slug attribute doing "Model.all.unset :slug".