将演示逻辑放在controller中是Ruby中的一个很好的做法?
-
12-12-2019 - |
题
一些建议[1]建议你使用
<%= current_user.welcome_message %>
而不是
<% if current_user.admin? %>
<%= current_user.admin_welcome_message %>
<% else %>
<%= current_user.user_welcome_message %>
<% end %>
但问题是你必须在代码的某个地方有决策逻辑。
我的理解是把决定放在 template
比...... controller
因为它使你的控制器更干净。这是正确的吗?
有更好的方法来处理这个问题吗?
解决方案
其他提示
你不是第一个怀疑这一点的人。如果视图和控制器应该几乎没有逻辑,并且模型应该是表示不可知的,那么表示逻辑属于哪里?
我们可以使用一种叫做 装饰器图案.我们的想法是用另一个包含演示逻辑的类包装模型对象。这个包装类被称为 装饰师.装饰器将逻辑从视图中抽象出来,同时使模型与演示文稿隔离开来。
德雷珀 是一个优秀的宝石,有助于定义装饰者。
你给出的示例代码可以像这样抽象出来:
将装饰器传递给视图 @user = UserDecorator.new current_user
在你的控制器里。
您的装饰器可以如下所示。
class UserDecorator
decorates :user
def welcome_message
if user.admin?
"Welcome back, boss"
else
"Welcome, #{user.first_name}"
end
end
end
你的观点将简单地包含 @user.welcome_message
请注意,模型本身不包含创建消息的逻辑。相反,装饰器包装模型并将模型数据转换为可呈现的形式。
希望这有帮助!
我会使用帮助者。假设您必须根据某些区域设置翻译欢迎 - 消息。
在app/helper/user_helper.rb
write 中
module UserHelper
def welcome_message(user)
if user.admin?
I18n.t("admin_welcome_message", :name => user.name)
else
I18n.t("user_welcome_message", :name => user.name)
end
end
end
.
和在您的视图中,您可以只写
<%= welcome_message(user) %>
.
请注意,装饰器/介绍者提供了一个真正清洁的面向对象的方法,但使用助手的imho更简单,足够了。
否,您不希望在用户类中的所有条件中都是控制器。博客帖子上的该示例是参考多态性,只是良好的老式OO设计。
# in application_controller for example
def current_user
if signed_in?
User.find(session[:user_id])
else
Guest.new
end
end
#app/models/user.rb
class User
def welcome_message
"hello #{name}"
end
end
#app/models/guest.rb
class Guest
def welcome_message
"welcome newcomer"
end
end
.
......你得到了这个想法。 只有,而不是使用仅呈现的方法乱丢模型,而是创建作为演示者的装饰器:
require 'delegate'
class UserPresenter < SimpleDelegator
def welcome_message
"hello #{name}"
end
end
.
,现在current_user
看起来如此:
# application_controller
def current_user
if signed_in?
UserPresenter.new(User.find(session[:user_id]))
else
Guest.new
end
end
. 装饰用户模型并直接添加欢迎_Message。是的,这可能涉及某些条件陈述。
http://robots.thoughtbot.com/post/14825364877 /评估 - 替代装饰器 - 实现 - 在
我想你应该在演示者上观看railscasts剧集的答案。
逻辑在视图中很难维护,我们应该将业务逻辑放在模型中,并在助手中的所有视图逻辑。
如果您希望您的代码以面向对象的方式,请使用装饰器(面向对象的助手方式)
把代码定义 current_user.welcome_message
在_app/helpers/application_helper中。rb_,然后它将被任何使用 申请表格 布局。
另一种选择是定义一个 海关规定 助手模块,一个不一定与给定的视图或控制器相关联(请参阅下面我链接的视频),以及 include
它在您希望具有该功能的视图/控制器的模块中。
这不是黑白的东西。但是,从您所描述的内容来看,这听起来像是坚持在application_controller中的代码。rb和它不是具有证明它自己的控制器的功能的代码,最有效和有效的选择可能是创建一个自定义帮助器模块并将其包含在您希望具有该功能的帮助器中。也就是说,这最终是应用程序设计者的判断调用(即 你)需要决定。
这里 是一篇很好的文章,概述了帮助模块 2011年5月
这里 is是一条铁路概述 海关规定 辅助模块(即自定义模块不一定与给定的控制器或视图相关联)。简短,甜蜜,直截了当。
您可以为该东西定义帮助方法。我不认为这是一个好主意在模型中制作一个受欢迎的句子,而是在控制器中也是如此。但是你应该尝试从代码中查看清单,如果您可以使用助手,那么您应该使用。
良好的做法是拥有真正的世代天线典礼实例。Rails MVP的模仿(有区别,看起来,似乎似乎似乎假装观点是模板。那是错误的。
视图应该包含MVC和MVC启发模式中的演示逻辑。它们也应该操纵多个模板,并在哪个模板上做出模板来代表模型层的状态和信息(是,模型是一个也不是ORM实例)。
所以,回答问题:呈现逻辑在控制器中没有位置。