Rails Mongoid : 查询嵌入文档并访问 Mongoid 条件
Rails Mongoid : Query embedded document and access to Mongoid criteria
我有一个应用程序,用户可以创建很多旅行,他们可以邀请他们的 facebook 好友。在旅行证件中,有一个字段"participants"是一个嵌入文档,Participant
模型嵌入在Travel
模型中。
这是我的模型:
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')}
您的嵌入式文档可能有一个 string 字段,例如:
"user_id": "592c8da58511989ec850921e"
而不是您要查找的ObjectId
:
"user_id": ObjectId("592c8da58511989ec850921e")
因此,由于类型不匹配,您将找不到您要查找的内容。
要么修复嵌入字段的类型:
field :user_id, type: BSON::ObjectId
或按字符串查询:
Travel.where('participants.user_id' => @user.id.to_s)
更改类型将涉及修复您已有的任何数据,以不同的方式更改查询是丑陋的。
有时 Mongoid 会为您在字符串和 ObjectId 之间进行转换,有时不会。当我使用 Mongoid 时,我将 to_bson_id
方法修补到 BSON::ObjectId
、String
、Mongoid::Document
、...这样我就可以说:
Model.where(:some_id => some_id.to_bson_id)
而且不必经常担心 some_id
是什么类型。我还确保所有 ID 字段始终指定为 BSON::ObjectId
.
我有一个应用程序,用户可以创建很多旅行,他们可以邀请他们的 facebook 好友。在旅行证件中,有一个字段"participants"是一个嵌入文档,Participant
模型嵌入在Travel
模型中。
这是我的模型:
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')}
您的嵌入式文档可能有一个 string 字段,例如:
"user_id": "592c8da58511989ec850921e"
而不是您要查找的ObjectId
:
"user_id": ObjectId("592c8da58511989ec850921e")
因此,由于类型不匹配,您将找不到您要查找的内容。
要么修复嵌入字段的类型:
field :user_id, type: BSON::ObjectId
或按字符串查询:
Travel.where('participants.user_id' => @user.id.to_s)
更改类型将涉及修复您已有的任何数据,以不同的方式更改查询是丑陋的。
有时 Mongoid 会为您在字符串和 ObjectId 之间进行转换,有时不会。当我使用 Mongoid 时,我将 to_bson_id
方法修补到 BSON::ObjectId
、String
、Mongoid::Document
、...这样我就可以说:
Model.where(:some_id => some_id.to_bson_id)
而且不必经常担心 some_id
是什么类型。我还确保所有 ID 字段始终指定为 BSON::ObjectId
.