0

I am using mongoid 3 in a rails 3 application.

I have a client class with referenced object 'files' (so instances of a custom 'LocalisedFile' class.)

Client.rb:

class Client
    include Mongoid::Document
    include Mongoid::Timestamps
    store_in collection: 'clients'

    field :name, type: String

    has_many :files, class_name: 'LocalisedFile', inverse_of: :owner
end

LocalisedFile.rb:

class LocalisedFile
    include Mongoid::Document
    include Mongoid::Timestamps
    include Geocoder::Model::Mongoid
    store_in collection: 'files'

    belongs_to :owner, class_name: 'Client', inverse_of: :files
end

No problem to manage my documents.

But when I want to render an array of files, I just get a "owner_id" field with the client string id...

[(2)
    {
        "_id": "508e85e412e86a2607000005",
        "created_at": "2012-10-29T13:34:29Z",
        "owner_id": "508c06e4bcd7ac4108000009",
        "title": "Try",
        "updated_at": "2012-10-29T13:34:29Z",
    },-
    {
        "_id": "508e8c5312e86a2607000006",
        "created_at": "2012-10-29T14:01:56Z",
        "owner_id": "508c06e4bcd7ac4108000009",
        "title": "2nd Try",
        "updated_at": "2012-10-29T14:01:56Z",
    }-
]

That's maybe normal, but I would like to get the clients informations, to use it in a JS application with Google Maps API, like this :

[(2)
    {
        "_id": "508e85e412e86a2607000005",
        "created_at": "2012-10-29T13:34:29Z",
        "owner": {
            "_id": "508c06e4bcd7ac4108000009",
            "name": "Client 1"
        },
        "title": "Try",
        "updated_at": "2012-10-29T13:34:29Z",
    },-
    {
        "_id": "508e8c5312e86a2607000006",
        "created_at": "2012-10-29T14:01:56Z",
        "owner": {
            "_id": "508c06e4bcd7ac4108000009",
            "name": "Client 1"
        },
        "title": "2nd Try",
        "updated_at": "2012-10-29T14:01:56Z",
    }-
]

Anyone have an idea ? I would like to test something like the to_hash method but it does not work...

Flo Schild
  • 5,104
  • 4
  • 40
  • 55

1 Answers1

1

Since you're using a referenced relation between Client and LocalisedFile, the client's data does not get replicated inside the file objects, only the owner_id, to make the relation work. You need to access the client data through the owner relation you defined on the LocalisedFile model. For example:

l = LocalisedFile.first
l.owner.id # returns the id of the owner
l.owner.name # returns the name of the owner

To create the kind of output you need, I'd suggest abstracting this into an instance method with something like:

class LocalisedFile
  def as_hash_with_owner
    hash = self.to_hash
    hash[:owner] = { _id: self.owner.id, name: self.owner.name }
    hash.except[:owner_id]
  end
end

Then you can do something like:

files = LocalisedFile.all.entries # or whatever criteria
files.map { |f| f.as_hash_with_owner }

This should give you a ruby array of hashes which you can then convert to JSON or whatever format you need.

Vickash
  • 1,076
  • 8
  • 8
  • Thank you a lot for your answer, excepted that in a Mongoid context, the method #to_hash does not exists for a model. But with the #as_document method, it seems to work. So when I debug the hash in the model (inside the #as_hash_with_owner method), It's well. But how sould I return it ? Because the results are not changed in the controller... files = LocalisedFile.all files.map { |f| f.as_hash_with_owner } logger.debug "Files: #{files}" respond_to do |format| format.json { render :json => files.to_json, :status => :ok } end Does not seems to work... – Flo Schild Nov 01 '12 at 17:15
  • #to_hash should be called on a document, not a criteria or the model class. I'm using Mongoid 3.0.9 also, not sure if this may not exist in older versions. #to_json also works fine. Looks like the problem is somewhere in your controller. – Vickash Nov 01 '12 at 19:50
  • On second thought, if you're going to be doing a lot of this, you should probably check out jbuilder: https://github.com/rails/jbuilder – Vickash Nov 01 '12 at 19:51
  • Okay I will take a look to Jbuilder ! Thank you a lot again ! I'm using Mongoid 3.0.9 too, but I'm in a model context... – Flo Schild Nov 02 '12 at 02:22
  • I just had forgotten a return @hash on my #as_hash_with_owner method. It works, thank you a lot ! – Flo Schild Nov 02 '12 at 15:27