设计在登录/注销用户上进行n + 1个查询

时间:2013-09-27 22:14:27

标签: ruby-on-rails devise nested mongoid

我有一个rails 3 / mongoid应用程序,我使用设计登录,每次发生(登录或注销),不仅加载了用户(我期望),但它的所有配置文件(其中4个)也被加载通过mongo。像这样:

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难以做到这一点?

感谢您的帮助!

1 个答案:

答案 0 :(得分:0)

正如@rubish所说的那样,Devise的Trackable模块每次登录或注销时都会保存User对象。它明确使用save()方法。但为什么它不仅保存用户,而且还搜索所有用户的关系并保存它们?因为我有:

accepts_nested_attributes_for :admin_user, :publisher ...

和Mongoid文档一样:

  

请注意,自动保存功能会自动添加到   使用accepts_nested_attributes_for或验证时的关系   存在关系。

所以自动保存,这不是Mongoid中的默认行为,因为这行代码而被踢了。

我为解决这个问题所做的是将 accepts_nested_attributes_for 放在我的每个配置文件模型中而不是用户中。 我必须更改使用嵌套的配置文件创建用户的表单。现在,表单创建了一个嵌套用户的配置文件。 为了实现这一点,我必须覆盖Devise RegistrationsController以不同方式创建资源模型。但那是另一个话题=)