【问题标题】:View presenters in rails在 Rails 中查看演示者
【发布时间】:2014-03-11 19:17:41
【问题描述】:

我最近看到 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

如何创建装饰器数组?

【问题讨论】:

  • 我想这可能与 @users 中正在迭代的记录数有关。用户数量增加了吗?
  • 不,我使用的是完全相同的数据集。谢谢

标签: ruby-on-rails ruby mvp


【解决方案1】:

有几个地方可以改进代码。

首先,确保您的@users 在传递给视图之前已经在控制器中进行了装饰。好处:

  1. 这样你根本不需要编辑原始模板,只需使用相同的@users

  2. 您的视图与您使用的任何呈现/装饰模式都是分离的,并且确实有很多选择。您也可以选择在未触及视图的情况下不使用它。

  3. 理论上这应该更快,因为如果你在视图中单独装饰项目,计算机需要一次又一次地加载相关模块,与批量相比。

其次,渲染 collection 而不是迭代视图。根据我的经验,这更快。

代替

- @users.each do |user|
   = render_partial "user_thumb", user: user

= render partial: "user_thumb", collection: @users

【讨论】:

  • 感谢您的回复。您能否详细说明一下“确保您的用户在传递给视图之前已经在控制器中进行了装饰”。我使用的是演示者,而不是装饰者。虽然都是装饰器模式的形式,但是还是有区别的
  • @HereToLearn,我使用 Draper gem,所以我只输出@users.decorate。即使您使用其他解决方案,您也可以在控制器的最后一步中输出@users = present(@users)。如果您的演示者无法处理集合,最好改进它。
  • 这是一个很好的观点,我确实需要改进它,太糟糕了原来的rails cast,没有说怎么做。我想我得自己去找,如果你有什么好建议的话。谢谢
  • 演员阵容非常适合从头开始学习这个想法。对于使用情况,您可以检查现有的 gem 或改进想法。
  • 还有一件事,我想我现在明白你的意思了。我发现 draper 是处理这类事情的好选择,我按照你说的在控制器中装饰我的所有对象,但是当我 .each 在 user_thumb 中进行集合时,我仍然得到用户对象而不是装饰器
猜你喜欢
  • 1970-01-01
  • 2016-02-24
  • 1970-01-01
  • 2012-05-09
  • 1970-01-01
  • 1970-01-01
  • 2011-08-18
  • 1970-01-01
  • 2022-10-02
相关资源
最近更新 更多