Antonin Mrchd
Antonin Mrchd

Reputation: 666

Rails Mongoid : Query embedded document and access to Mongoid criteria

I have an application where users can create many travels, and they can invite their facebook friends. In the travel document, there is a field "participants" that is an embedded document, Participant model embedded in Travel model. example

Here are my models :

class Travel
  include Mongoid::Document
  include Mongoid::Timestamps

  # relations
  belongs_to :user

  # fields
  field :title, type: String
  field :description, type: String
  field :begin_date, type: Date
  field :end_date, type: Date
  field :budget, type: Integer
  field :go_back, type: Boolean
  field :title_namespace, type: String

  # friends
  embeds_many :participants
  accepts_nested_attributes_for :participants

end

class Participant
  include Mongoid::Document
  include Mongoid::Timestamps

  field :name, type: String
  field :user_id, type: String

  # relations
  embedded_in :travel, :inverse_of => :participants

end

When I try to display travel where users have been invited, with this request :

@travel_participations = Travel.where('participants.user_id' => @user.id)

I don't have any result, even if I have this line in byebug :

#<Mongoid::Criteria
  selector: {"participants.user_id"=>BSON::ObjectId('592c8da58511989ec850921e')}
  options:  {}
  class:    Travel
  embedded: false>

So when I put this on my view :

<% unless @participations.nil? %>
  <% @travel_participations.each do |travel_participation| %>
    <p> <%= travel_participation.title %> </p>
  <% end %>
<% end %>

I tried with .all, .first, .to_a, .as_json, no results ... Some one know where is the problem ?

Upvotes: 1

Views: 1252

Answers (1)

mu is too short
mu is too short

Reputation: 434585

You have this in your embedded model:

field :user_id, type: String

but your query is using a BSON::ObjectId:

Travel.where('participants.user_id' => @user.id)

as shown in the raw query:

selector: {"participants.user_id"=>BSON::ObjectId('592c8da58511989ec850921e')}

Your embedded document probably has a string field like:

"user_id": "592c8da58511989ec850921e"

rather than the ObjectId you're looking for:

"user_id": ObjectId("592c8da58511989ec850921e")

so you won't find what you're looking for due to the type mismatch.

Either fix the embedded field's type:

field :user_id, type: BSON::ObjectId

or query it as the string it is:

Travel.where('participants.user_id' => @user.id.to_s)

Changing the type will involve fix up whatever data you already have, changing the query is ugly in a different way.

Sometimes Mongoid will convert between strings and ObjectIds for you, sometimes it won't. When I used Mongoid I patched to_bson_id methods into BSON::ObjectId, String, Mongoid::Document, ... so that I could say things like:

Model.where(:some_id => some_id.to_bson_id)

and not have to constantly worry about what type some_id was. I also made sure that all ID fields were always specified as BSON::ObjectId.

Upvotes: 1

Related Questions