Mongoid:搜索has_many关系

时间:2013-04-08 16:41:34

标签: ruby-on-rails mongodb mongoid

我正在使用mongoid,并且有以下代码:

class Users::User
  include Mongoid::Document
  field :username, type: String
  has_many :emails, class_name: "Users::Email"
end

class Users::Email
  include Mongoid::Document

  field :email, type: String

  belongs_to :user, class_name: "Users::User", inverse_of: :emails
end

数据库:

#users collection
{
  "_id" : ObjectId("5162de8a359f10cbf700000c"),
  "username" : "bilbo"
}

#emails collection
{
  "_id" : ObjectId("5162de8a359f10cbf700000b"),
  "email" : "bilbo@jenkins.com",
  "user_id" : ObjectId("5162de8a359f10cbf700000c"),
}

我试图通过以下查询找到:

Users::User.includes(:emails).any_of({username: login},{"emails.email"=> login}).first

我不知道为什么,但这个查询忽略了电子邮件关系中的搜索。 当login = "bilbo" =>是的,但login = "bilbo@jenkins.com" =>零

那么,我做错了什么?

1 个答案:

答案 0 :(得分:3)

你需要一个联接来做你想做的事情而且Mongoid没有联接。如果您只需要通过用户访问电子邮件,则可以对其进行非规范化并将其嵌入Users::User

class Users::User
  include Mongoid::Document
  field :username, type: String
  embeds_many :emails, class_name: "Users::Email"
end

class Users::Email
  include Mongoid::Document

  field :email, type: String

  embedded_in :user, class_name: "Users::User", inverse_of: :emails
end

这样,您就可以查询用户的电子邮件:

irb(main):011:0> login = "bilbo@jenkins.com"
=> "bilbo@jenkins.com"
irb(main):012:0> Users::User.any_of({username: login},{"emails.email"=> login}).first
=> #<Users::User _id: 5163ee96e44f7b0301000001, username: "bilbo">

如果Users::Email的唯一属性为email,您可以更进一步,完全省略模型并将字符串存储在数组中:

class Users::User
  include Mongoid::Document
  field :username, type: String
  field :emails, type: Array
end

查询变得更加容易:

Users::User.any_of({username: login},{"emails"=> login}).first
=> #<Users::User _id: 5163ef95e44f7b6254000001, username: "bilbo", emails: ["bilbo@jenkins.com"]>