Skip to content

undefined method to_hash' for class Elasticsearch::Model::Response::Result' #430

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
johaned opened this issue Jun 20, 2015 · 4 comments
Closed
Labels

Comments

@johaned
Copy link

johaned commented Jun 20, 2015

I cannot use Model.search({}).to_a and similar methods when I am using Mongoid, I have the following code:

# app/models/user.rb
# Code extracted from a devise model, also it is using Mongoid 4.0.2 as its ODM
class User
  include Mongoid::Document
  include Elasticsearch::Model
  include Elasticsearch::Model::Callbacks

  index_name "users-#{Rails.env}"

  field :email, type: String, default: ""
  field :first_name, type: String, default: ""
  field :last_name, type: String, default: ""

  def as_indexed_json
    as_json(except: [:_id])
  end

end

I have created my index like this:

  User.__elasticsearch__.create_index! force: true
  User.import

but the search does not work when I try to use the array's methods

  User.search('allam').to_a
  #=> output error: #<NameError: undefined method `to_hash' for class `Elasticsearch::Model::Response::Result'>

I only can use the following code

  User.search('allam').records.to_a

But I do not want to hit the database for retrieving the searched documents

Perhaps did I miss some step?

Thank you for your support!

@karmi
Copy link
Contributor

karmi commented Jun 20, 2015

Hi, this is really surprising, can you investigate the Mongoid example avaialable here: https://github.com/elastic/elasticsearch-rails/blob/master/elasticsearch-model/examples/mongoid_article.rb ? I've tried it now and it works.

Also notice that you can do User.search('allam').results.to_a to load the documents from Elasticsearch, instead from database.

@johaned
Copy link
Author

johaned commented Jun 20, 2015

Hi, yesterday I also tried the option that you suggested me: Model.search({}).results.to_a, but I got the same error.

Today I have tried with the example code, and as you mentioned before, it works!

However, in my case the search is still failing, I have made an example project (it is based on a rails template) and I have pushed it to my github here

my key files are the following:

# app/models/book.rb
class Book
  include Mongoid::Document
  include Elasticsearch::Model
  include Elasticsearch::Model::Callbacks

  index_name "books-#{Rails.env}"

  field :title, type: String
  field :author, type: String

  def as_indexed_json(options={})
    as_json(except: [:id, :_id])
  end
end
# config/initializers/elasticsearch.rb
Elasticsearch::Model.client = Elasticsearch::Client.new url: ENV['ELASTICSEARCH_URL'] || 'http://localhost:9200'

# Book.__elasticsearch__.client.indices.delete index: Book.index_name rescue nil

unless Book.__elasticsearch__.index_exists?
  Book.__elasticsearch__.create_index! force: true
  Book.import
end

This is strange because some days ago I had almost the same configuration but using PostgreSQL and it worked

Also notice that I can perform some actions on the results object, for example (based on my example project)

Book.search('Children').results.count
#=> 1

But when I try to call some array's methods it breaks

Book.search('Children').results.to_a
#=> (pry) output error: #<NameError: undefined method `to_hash' for class `Elasticsearch::Model::Response::Result'>

@johaned
Copy link
Author

johaned commented Jun 22, 2015

Hi,

(Sorry for my english...) I have found the error, at the beginning I was thinking that it could be related with my Pry configuration, I'm using the jazz_hands gem, but in summary the problem was focused on this part of code:

Pry.config.print = ->(output, value, _pry_) do
  return if JazzHands._hirb_output && Hirb::View.view_or_page_output(value)
  pretty = value.ai(indent: 2) # <-- ERROR
  _pry_.pager.page("=> #{pretty}")
end

value is an instance of Elasticsearch::Model::Response::Result and the "ai" method is an alias for awesome_inspect, and the real problem was focused on this method (source available here)

what is happening here is that when this method (awesome_inspect) is invoked and the value is a kind of Hash instance (Hashie in this case) there is a method that is invoked for formatting the value which is named "convert_to_hash" (source available here), inside this method we have the following situation:

Elasticsearch::Model::Response::Result#respond_to? :to_hash
#=> true

but,

Elasticsearch::Model::Response::Result#method :to_hash
#=> NameError: undefined method `to_hash' for class `Elasticsearch::Model::Response::Result'

so this is replicable when for example I use awesome_print directly, (in my example project without the jazz_hands gem)

Book.search('Children').results.to_a # it works!
#=> [#<Elasticsearch::Model::Response::Result:0x007f8b82903f48 @result=#<Hashie::Mash _id="5588213f4a75612cc5010000" _index="books-development" _score=0.4375 _source=#<Hashie::Mash author="Ian McEwan" title="The Children Act"> _type="book">>]

ap Book.search('Children').results.to_a.first  # it does not work                   
#=> NameError: undefined method `to_hash' for class `Elasticsearch::Model::Response::Result'

Book.search('Children').results.to_a.first.method(:to_hash) # it does not work 
#=> NameError: undefined method `to_hash' for class `Elasticsearch::Model::Response::Result'

What I did for solving the problem was to make a method named 'to_hash' inside the Elasticsearch::Model::Response::Result class (source available here), all the tests are running but I don't know if this solution is ok (also I have tested this solution using both ActiveRecord and Mongoid and it works!), however, I have made a pull request but I had a problem with my CLA (I already have one but it does not work, I'll back in 60 minutes).

What do you think about my simple solution @karmi ?

@stale
Copy link

stale bot commented Aug 31, 2020

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

@stale stale bot added the stale label Aug 31, 2020
@stale stale bot closed this as completed Sep 7, 2020
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants