2013-09-27 34 views
0

我有一個rails 3/mongoid應用程序,我使用devise登錄,並且每次發生(登錄或註銷)時,不僅用戶被加載(我期望),但所有的配置文件(其中4個)也由mongo加載。像這樣:在登錄/註銷時設計n + 1查詢用戶

MOPED: 127.0.0.1:27017 QUERY  database=asgard_development collection=advertisers selector={"$query"=>{"user_id"=>"51facd99615956fdb4000026"}, "$orderby"=>{:_id=>1}} flags=[:slave_ok] limit=-1 skip=0 batch_size=nil fields=nil (0.6170ms) 
    MOPED: 127.0.0.1:27017 QUERY  database=asgard_development collection=publishers selector={"$query"=>{"user_id"=>"51facd99615956fdb4000026"}, "$orderby"=>{:_id=>1}} flags=[:slave_ok] limit=-1 skip=0 batch_size=nil fields=nil (0.7150ms) 
    MOPED: 127.0.0.1:27017 QUERY  database=asgard_development collection=regular_users selector={"$query"=>{"user_id"=>"51facd99615956fdb4000026"}, "$orderby"=>{:_id=>1}} flags=[:slave_ok] limit=-1 skip=0 batch_size=nil fields=nil (0.5891ms) 
    MOPED: 127.0.0.1:27017 QUERY  database=asgard_development collection=admin_users selector={"$query"=>{"user_id"=>"51facd99615956fdb4000026"}, "$orderby"=>{:_id=>1}} flags=[:slave_ok] limit=-1 skip=0 batch_size=nil fields=nil (0.6969ms) 

這太多了!我想到Devise正在構建User對象及其所有關係。但是,這不應該是懶惰?

我的用戶是這樣的:

class User 

    ##Includes begin 
    include Mongoid::Document 
    include Mongoid::Timestamps 
    include Roles 
    ##Includes end 

    ##Scopes begin 
    ##Scopes end 

    ##Constants begin 

    ##Constants end 

    ##Extras begin 



    # Include default devise modules. Others available are: 
    # :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable 
    devise :database_authenticatable, :lockable, :registerable, :recoverable, :rememberable, :trackable, :validatable 
    ##Extras end 

    ##Relationships begin 
    has_one :admin_user 
    has_one :regular_user 
    has_one :publisher 
    has_one :advertiser 
    accepts_nested_attributes_for :admin_user, :regular_user, :publisher, :advertiser 

我想避免或縮小做N + 1(其中n爲配置文件數量的用戶可以)查詢每次用戶登錄。爲什麼設計/ mongoid這樣做很難?

感謝您的幫助!

+0

我使用的設計與rails 3.2.13 mongoid並沒有這樣的問題!什麼是admin_user,regular_user,發佈者和廣告客戶?他們是用戶嗎?或者是與用戶直接相關的東西?你有沒有試過[Mongoid Indentity Map](http://mongoid.org/en/mongoid/docs/identity_map.html)?你的關於查詢的服務器日誌說,它加載完全相同的用戶4次! 正如我看到每個嵌套模型加載自己的用戶實例,所以mongoid查詢該實例的用戶!這就是問題所在! –

+1

我認爲你有一些驗證用戶啓動這些查詢。如果用戶可以跟蹤登錄/註銷時保存,並會導致驗證運行。 – rubish

+0

@KiT O:admin_user,regular_user等都是用戶的個人資料。用戶只是具有電子郵件和密碼的設計默認用戶。根據用戶配置文件,它有不同的領域和關係。例如,一位用戶可以是管理員和發佈者。但是,每個嵌套模型構建用戶模型是沒有意義的,因爲在這種情況下用戶是「父」。這會導致無限循環。是的,我正在使用身份地圖。 –

回答

0

會發生什麼,就像@rubish說的那樣,Devise的Trackable模塊每次登錄或註銷時都會保存User對象。它明確使用save()方法。但是,爲什麼它不僅保存用戶,還要搜索所有用戶的關係並保存它們?因爲我有一個:

accepts_nested_attributes_for :admin_user, :publisher ... 

而像Mongoid文件說:

注意,使用accepts_nested_attributes_for或驗證 存在的關係時,自動保存功能將自動被添加到 關係。

因此,由於該行代碼的原因,自動保存不是默認行爲,而是在Mongoid中啓動的。

我所做的解決這個問題的方法是將acceptable_nested_attributes_for放在我的每個配置文件模型中而不是User中。 我不得不改變用嵌套配置文件創建User的窗體。現在,表單將創建一個用戶嵌套的配置文件。 爲了達到這個目的,我不得不重寫Devise RegistrationsController以不同的方式創建資源模型。但這是另一個話題=)