Pregunta

I don't know exactly should it works how i expect or not, but i think that this:

  def show
    render json: Book.includes(:genres).find(params[:id])
  end

Should include genres in book model.

class Book
  include Mongoid::Document
  ...

  has_and_belongs_to_many :genres
end

class Genre
  include Mongoid::Document

  field :name, type: String
end

But on client in contains only list of genre ids.

genre_ids: Array[1]
  0: Object
  $oid: "53532d3b616c6439c1070000"

I also tried another model Author with book:

class Author
  include Mongoid::Document

  field :name, type: String

  has_many :books, inverse_of: :author
end

# in controller action

render json: Book.includes(:author).find(params[:id])

# returns =>
#    {"book":{"_id":{"$oid":"53532d3b616c6439c1140000"},"annotation":null,"author_id":{"$oid":"53532d3b616c6439c1000000"},"author_name":"Сомерсет Моэм","co_author_ids":[],"created_at":"2014-04-20T02:13:16.057Z","date":"1947","genre_ids":[{"$oid":"53532d3b616c6439c1070000"}],"html_path":"/Users/alder/Projects/pro_book_reader/rails-api/storage/GoCUMSZP/_.html","image_url":"GoCUMSZP.jpg","name":"Театр","toc_path":null,"token":"h9beplTN"}}

Same thing, it returns only $oid (author_name is a book model property)

So, could i load all genres models with book model, without extra queries?

Rails 4.1, mongoid 4.0.0.beta1

Also i don't have association in Genre model, because it will save all book ids in genre model.

UPDATED

Identity Map has been removed from mongoid 4. There is new preload_models option, but it's not load genres too when true.

PS

It works with render json: {book: book, genres: book.genres}, so maybe thats fine until includes will be fixed.

PS2

I think perhaps this includes is not what i'm thinking of. I mean maybe it's just helps to avoid extra queries after you appeal to relational model(s). And it doesn't create array from all childs, or add author object to author field (that what any expect, not useless ID).

¿Fue útil?

Solución

To display genres for each of all available books:

def show 
  books = Book.all 
  render json: books, include: :genres 
end

To display genres for a particular book:

def show 
  book = Book.find(params[:id]) 
  render json: book, include: :genres 
end

Otros consejos

You have to enable the identity map in mongoid.yml for eager loading to work

identity_map_enabled: true

in options.

Identity Map has been removed from mongoid master (mongoid4). You can check with the issue opened for further details, https://github.com/mongoid/mongoid/issues/3406.

Also mongoid 4 change log shows in Major Changes (Backward Incompatible) as identity map is removed. https://github.com/mongoid/mongoid/blob/006063727efe08c7fc5f5c93ef60be23327af422/CHANGELOG.md.

As they suggested, Eager load will work without identity map now.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top