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

问题描述:

我有一个应用程序,用户可以创建很多旅行,并且他们可以邀请他们的Facebook好友。在旅行证件中,有一个字段“参与者”是一个嵌入文件,Participant模型嵌入在Travel模型中。 exampleRails Mongoid:查询嵌入式文档并访问Mongoid标准

这里是我的模型:

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,没有结果......有些人知道问题出在哪里?

你在你的嵌入式型号有这样的:

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

+1

完美的答案,很明显,我有解释,很多朋友的感谢!我将你的答案标记为已接受! –

+1

那么,没有解释的答案不会很多,是吗?字符串和ObjectIds之间的区别非常烦人。 –