Rails Mongoid:查询嵌入式文档并访问Mongoid标准

时间:2017-06-01 20:58:36

标签: ruby-on-rails mongodb mongoid

我有一个应用程序,用户可以创建许多旅行,他们可以邀请他们的Facebook朋友。在旅行证件中,有一个字段“参与者”是嵌入在Participant模型中的嵌入式文档Travel模型。 example

以下是我的模特:

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

当我尝试使用此请求显示邀请用户的旅行时:

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

我没有任何结果,即使我在byebug中有这一行:

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

所以,当我把它放在我的观点上时:

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

我尝试使用.all.first.to_a.as_json,没有结果......有人知道问题出在哪里?

1 个答案:

答案 0 :(得分:1)

您在嵌入式模型中有这个:

field :user_id, type: String

但您的查询使用BSON::ObjectId

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

如原始查询中所示:

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

您的嵌入式文档可能包含字符串字段,如:

"user_id": "592c8da58511989ec850921e"

而不是您正在寻找的ObjectId

"user_id": ObjectId("592c8da58511989ec850921e")

因此,由于类型不匹配,您无法找到您要查找的内容。

修复嵌入字段的类型:

field :user_id, type: BSON::ObjectId

或将其作为字符串查询:

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

更改类型将涉及修复您已有的任何数据,以不同的方式更改查询是丑陋的。

有时Mongoid会为你转换字符串和ObjectIds,有时它会赢。当我使用Mongoid时,我将to_bson_id方法修补为BSON::ObjectIdStringMongoid::Document,...以便我可以这样说:

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

并且不必经常担心some_id是什么类型。我还确保所有ID字段始终指定为BSON::ObjectId