两种型号(Rails 2.3.8):
- 用户; 用户名和禁用属性;用户 has_one :profile
- 轮廓; 全名和隐藏属性
我正在尝试创建一个 named_scope 来消除 disabled=1 和 hidden=1 用户配置文件。User 模型通常与 Profile 模型一起使用,因此我尝试预先加载 Profile 模型(:include => :profile)。
我在名为“可见”的用户模型上创建了一个 named_scope:
named_scope :visible, {
:joins => "INNER JOIN profiles ON users.id=profiles.user_id",
:conditions => ["users.disabled = ? AND profiles.hidden = ?", false, false]
}
我注意到,当我在查询中使用 named_scope 时,会忽略急切加载指令。
变体 1 - 仅限用户模型:
# UserController
@users = User.find(:all)
# User's Index view
<% for user in @users %>
<p><%= user.username %></p>
<% end %>
# generates a single query:
SELECT * FROM `users`
变体 2 - 在视图中使用 Profile 模型;延迟加载配置文件模型
# UserController
@users = User.find(:all)
# User's Index view
<% for user in @users %>
<p><%= user.username %></p>
<p><%= user.profile.full_name %></p>
<% end %>
# generates multiple queries:
SELECT * FROM `profiles` WHERE (`profiles`.user_id = 1) ORDER BY full_name ASC LIMIT 1
SHOW FIELDS FROM `profiles`
SELECT * FROM `profiles` WHERE (`profiles`.user_id = 2) ORDER BY full_name ASC LIMIT 1
SELECT * FROM `profiles` WHERE (`profiles`.user_id = 3) ORDER BY full_name ASC LIMIT 1
SELECT * FROM `profiles` WHERE (`profiles`.user_id = 4) ORDER BY full_name ASC LIMIT 1
SELECT * FROM `profiles` WHERE (`profiles`.user_id = 5) ORDER BY full_name ASC LIMIT 1
SELECT * FROM `profiles` WHERE (`profiles`.user_id = 6) ORDER BY full_name ASC LIMIT 1
变体 3 - 急切加载配置文件模型
# UserController
@users = User.find(:all, :include => :profile)
#view; no changes
# two queries
SELECT * FROM `users`
SELECT `profiles`.* FROM `profiles` WHERE (`profiles`.user_id IN (1,2,3,4,5,6))
变体 4 - 使用 name_scope,包括预加载指令
#UserConroller
@users = User.visible(:include => :profile)
#view; no changes
# generates multiple queries
SELECT `users`.* FROM `users` INNER JOIN profiles ON users.id=profiles.user_id WHERE (users.disabled = 0 AND profiles.hidden = 0)
SELECT * FROM `profiles` WHERE (`profiles`.user_id = 1) ORDER BY full_name ASC LIMIT 1
SELECT * FROM `profiles` WHERE (`profiles`.user_id = 2) ORDER BY full_name ASC LIMIT 1
SELECT * FROM `profiles` WHERE (`profiles`.user_id = 3) ORDER BY full_name ASC LIMIT 1
SELECT * FROM `profiles` WHERE (`profiles`.user_id = 4) ORDER BY full_name ASC LIMIT 1
变体 4 确实返回了正确数量的记录,但似乎也忽略了急切加载指令。
这是跨模型命名范围的问题吗?也许我没有正确使用它。
Rails 3 能更好地处理这种情况吗?