Sam*_*rbi 5 ruby activerecord ruby-on-rails ruby-on-rails-3
模型:
class Project < ActiveRecord::Base
has_many :user_roles
after_initialize :add_user_roles
def add_user_roles
UserRoles.all.each do |ur|
self.user_roles << ur unless self.user_roles.include?(ur)
end
end
end
Run Code Online (Sandbox Code Playgroud)
查找项目的声明:
@projects = Project.includes(:user_roles)
Run Code Online (Sandbox Code Playgroud)
所以你可以看到,我告诉它在查询中包含用户角色关联.但是,我仍然看到n + 1查询问题:它为每个项目找到一次角色.
如果我self.user_roles从回调中删除使用并查看日志,我可以看到它在2个查询中找到项目及其用户角色 - 一个用于项目,一个用于角色使用project_id in (1,2,3,4,5...,n).
有办法解决这个问题吗?
让我澄清一点:虽然我愿意在需要时解决我的具体情况,但我更喜欢那些专注于如何解决问题的答案.我能够编写一个kludge来使数据处于我想要的状态而不使用after_initialize回调,因此不会进入n + 1查询问题.但是,我宁愿不这样做,所以我更喜欢一般问题的答案而不是我的具体例子.
看看rails eager loading http://guides.rubyonrails.org/active_record_querying.html#eager-loading-associations
您可以在使用加载对象时加载关联 includes
User.find(2).includes(:assets)#will load all assets with user
Run Code Online (Sandbox Code Playgroud)
或者您可以在模型中指定急切加载关联
应用程序/模型/ user.rb
class User< AR::Base
has_many :posts,:include=>:comments
end
class Post < AR::Base
has_many :comments
belongs_to :user
end
Run Code Online (Sandbox Code Playgroud)
现在u.posts将为每个帖子加载评论
小智 2
即使是急切加载的关联也不可用(它们在记录初始化后after_initialize加载)。请参阅这个 Rails 问题进行一些讨论:
https://github.com/rails/rails/issues/13156
与最初的问题相关:看起来每个项目都会有相同的UserRole对象集。我猜有一个has_many :through已经被清理掉了,但即便如此,怎么会Project最终没有全套呢?我没有看到Project和UserRole在这里实际上是如何连接的 - 从示例中可见,这是:
class Project < ActiveRecord::Base
def user_roles
UserRole.all
end
end
Run Code Online (Sandbox Code Playgroud)
after_initialize会完成与...相同的事情
| 归档时间: |
|
| 查看次数: |
4321 次 |
| 最近记录: |