2012-03-19 78 views
0

查詢我有以下型號:mongoid - 如何通過嵌入對象

class User 
    include Mongoid::Document 
    store_in :users 

    field :full_name, :type => String 
end 

class Message 
    include Mongoid::Document 

    embeds_one :sender, :class_name => "User" 

    field :text,  :type => String 
end 

我想用來存儲UserMessage在分開獨立的集合,使他們可以直接查詢,我想有每個消息條目中的sender的用戶的一個副本。我的模型對於這種請求是否正確?

而當我有一個用戶user的實例,我怎麼能查詢哪些消息sender = user

我已經試過: Message.where(:sender => user) Message.where('sender.id' => user.id) 都無法正常工作。

只有Message.where('sender.full_name' => user.full_name)工作,但我不想依靠文本字段,當有一個ID字段使用。

這樣做的最佳方法是什麼?

我如何保存訊息/用戶:

user = User.new 
user.full_name = 'larry' 
user.save 

m = Message.new(:text => 'a text message') 
m.sender = user 
m.save 

而且這將導致數據庫:

> db.users.find({ 'full_name' : 'larry'}) 
> db.messages.find({})[0] 
{ 
     "_id" : ObjectId("4f66e5c10364392f7ccd4d74"), 
     "text" : "a text message", 
     "sender" : { 
       "_id" : ObjectId("4f62e0af03642b3fb54f82b0"), 
       "full_name" : "larry" 
     } 
} 
+0

這是正確的,畝。你可以將其轉換爲答案。但我仍感到有點困惑。因爲我總是覺得'Message.where(:sender => user)'應該是實現它的方法。 – larryzhao 2012-03-19 08:26:56

回答

1

像喬丹durran的(Mongoid主要開發人員)在谷歌組Mongoid的解釋:http://groups.google.com/group/mongoid/browse_thread/thread/04e06a8582dbeced#

你會需要一個獨立的模型,如果你要嵌入的用戶在郵件內 數據。當像這樣反規範化時,我通常使用 命名空間其中之一,並創建一個模塊,並在其中包含共同字段 - 也許在您的情況下,您可以將其稱爲發件人?

class Sender 
    include Mongoid::Document 
    include UserProperties 

    class << self 
    def from_user(user) 
     Sender.new(user.attributes) 
    end 
    end 
end 

class User 
    include Mongoid::Document 
    include UserProperties 
end 

module UserProperties 
    extend ActiveSupport::Concern 
    included do 
    field :full_name, type: String 
    end 
end 

class Message 
    include Mongoid::Document 
    embeds_one :sender 
end 

你也並不需要:對用戶store_in宏觀 - 默認情況下它的名字 將是「用戶」。

+0

優秀!雖然這是我在googlegroup發佈的實際上相同的問題,但我現在忘記回去查看:P。不幸的是,我可能不得不再次調整我的模型..我已經回到前幾天使用該參考。 – larryzhao 2012-03-20 09:57:44

+0

是的,我遵循谷歌組,這就是爲什麼我粘貼Durran答案在這裏。如果你在谷歌羣組上做了一個問題,你可以把你的問題連接起來。 – shingara 2012-03-20 12:53:58

+0

是的,我會在下次做。 – larryzhao 2012-03-20 13:45:01

1

你不能這樣做,你做什麼。

您的用戶文檔保存在他的一個集合中,因爲您使用的是store_in方法。並嘗試將其保存在其他文檔中(Message

如果你真的想要2集合,你需要在你的Message類中使用has_one :user

class Message 

    has_one :sender, :class_name => 'User', :foreign_key => 'sender_id' 

end 

後,你可以讓你的信息,如:

Message.senders有你所有的發件人。

+0

謝謝shingara,是的,我希望用戶和消息存儲在分離的集合中,但我希望在Message模型中有一個用戶副本作爲發件人,而不是引用。這是否意味着我應該'field:sender,:type => User'? – larryzhao 2012-03-19 08:41:19

+0

您需要在您的用戶類中添加一個'embedded_in:message' – shingara 2012-03-19 08:44:31

+0

然後用戶將被存儲在Message集合中,並且將無法直接進行查詢,我是否正確? – larryzhao 2012-03-19 08:54:05