我最近看到了Ryan Bates从头开始的一集主持人,这是主持人所做的一个很好的解释。这就是我所指的:
http://railscasts.com/episodes/287-presenters-from-scratch
所以我决定重构一些我的观点,因为里面有一些非常复杂的逻辑。
我的应用程序中有一个页面显示用户列表及其图像等。所以我所做的是我为每个用户呈现了一个部分,这就是它的工作方式。
在与演示者重构后,我得到了相同的部分,但所有逻辑都移到了演示者之外,视图只显示了值,但是我注意到为每个用户渲染部分需要两倍就像以前一样。
这是之前的(来自日志的数据):
Rendered users/_user_thumb.html.haml (6.4ms)
重构后:
Rendered users/_user_thumb.html.haml (18.5ms)
我已经查看了日志是否有一些额外的查询可以获得触发器或者什么,并且在重构代码时没有触发额外的查询。
我的问题是为什么这么慢?难道我做错了什么?
以下是我的代码现在的样子:
- @users.each do |user|
= render_partial "user_thumb", user: user
现在在渲染部分user_thumb
内部我有一个复杂的逻辑,但现在我有了这个:
- present user do |user_presenter|
....mycode here
我使用haml。
问题更新
比利在答案中有一些好处,所以我投了他的答案。我尝试了他的建议来装饰控制器中的@users
,如:
@users = UserDecorator.decorate(users)
然后我尝试检查它,我看到类似的东西:
#<UserDecorator:0x0000000966a6f8 @object=[#<User id: 8112 .....some users ], @context={}>
这是好事,我似乎立即让我的用户装饰。然后我尝试了比利的建议并做了:
= render partial: "user_thumb", collection: @users
但是当我在我的观点中尝试时:
collection.each do |u|
puts "#{user.inspect}"
end
我的装饰师看起来像:
class UserDecorator < Draper::Decorator
decorates :user
....
end
我得到用户而不是装饰用户为什么会这样?在装饰对象列表时这是如何工作的?如果最终你仍然得到用户对象,那么目的是什么?
这样可行,但它真的很慢:
- @users.each do |user|
= render_partial "user_thumb", user: user.decorate
如何创建装饰器数组?
答案 0 :(得分:2)
有几个地方可以改进代码。
首先,在传递给视图之前,确保您的@users
已在控制器中进行了装饰。好处:
通过这种方式,您根本不需要编辑原始模板,只需使用相同的@users
即可。
您的视图与您使用的任何现有/装饰模式分离,并且有很多选项。您也可以选择不使用未更改的视图。
理论上这应该更快,因为如果您在视图中单独装饰项目,计算机需要一次又一次地加载相关模块,与批处理相比。
其次,渲染collection
而不是迭代视图。根据我的经验,这更快。
而不是
- @users.each do |user|
= render_partial "user_thumb", user: user
待办事项
= render partial: "user_thumb", collection: @users