ruby-on-rails - 使用 ActiveSupport ``delegate to:'' 来干演示者实例方法
问题描述
多亏了Ryan Bates 的教程,我发现了演示者(或装饰者)模式,并在培训项目中实现了它。
我想知道是否有任何方法可以delegate
在自定义对象之间使用 ActiveSupport 方法?在重构我的第一个模型(产品)之后,我想在实例中使用一些ProductPresenter
实例方法CartPresenter
。如果没有,也许我应该使用演示者的担忧?
我目前正在视图中实例化演示者并通过将缺少的方法重定向到模板来访问辅助方法,但也许我需要在控制器中实例化演示者(以便同时访问CartPresenter
& ProductPresenter
)并为模板定义一个 getter(所以它不会'不要混淆method_missing
方法)?
编辑
感谢 jvillian 的回答,:product_presenter
现在指的是 ProductPresenter 实例。
因为我可能有其他需要委托演示者方法的情况,所以我添加:delegated_presenter
到我的BasePresenter
Class BasePresenter
def initialize(object, template)
@object = object
@template = template
end
def self.delegated_presenter(name)
define_method("#{name}_presenter") do
klass = "#{name.capitalize}Presenter".constantize
@delegator ||= klass.new(@object.send(name), @template)
end
end
end
现在在我的演示者子类中:
class CartPresenter < BasePresenter
delegated_presenter :product
delegate :product_presenter_instance_method, to: :product_presenter
end
我正在考虑将它们分组到一个 BasePresenter 类方法中,该方法将完成所有工作。
这是它在视图中的使用方式:
<% present product do |product_presenter| %>
<div class="card" style="width: 14rem;">
<%= product_presenter.display_card_image %>
<div class="card-body">
<%= product_presenter.display_link_to_product_name(class: 'card-title text-dark') %>
<%= product_presenter.display_link_to_product_supplier(class: 'small text-right') %>
<%= product_presenter.display_truncated_description(class: 'card-text') %>
<%= render partial: 'product_buttons', locals: { product: product } %>
<%= product_presenter.display_tags(class: 'badge badge-pill badge-secondary') %>
</div>
</div>
<% end %>
present
是返回演示者对象的辅助方法。
解决方案
这个:
delegate :my_instance_method, to: :product_presenter
...不起作用,因为:product_presenter
它是symbol
,而不是ProductPresenter
. 也许尝试更多类似的东西:
class CartPresenter
delegate :my_instance_method, to: product_presenter
def product_presenter
@product_presenter ||= ProductPresenter.new
end
end
...和...
class ProductPresenter
def my_instance_method
# do something
end
end
这个说法:
我目前正在视图中实例化演示者
...我有点担心,因为您正在视图和演示者之间创建紧密耦合。这是一个较长的主题,但如果我生成您在代码中显示的视图,它看起来更像:
<% @presenter = local_assigns[:presenter] if local_assigns[:presenter] %>
<div class="card" style="width: 14rem;">
<%= @presenter.card_content %>
</div>
然后,很自然地,你传入的任何 Presenter 都locals
需要实现card_content
. 现在,您的视图对除该一种方法之外的其他方法一无所知, . 您可以做任何您想做的事情,并在将来对方法进行更改,而不必担心更新您的视图。解耦!presenter
card_content
card_content
product_presenter
推荐阅读
- spring-boot - 如何将消息广播到所有套接字?
- bitbucket - Bitbucket 管道 - 缺少 PHP 扩展 zip
- json - 如何读取 $ussdResponse->Message 中的值
- r - 如何使用r中的两个向量和逻辑运算符形成逻辑“1”和“0”的矩阵?
- spring-mvc - Spring:@Valid 总是返回 False
- python-3.x - 通过删除无穷大来创建数组
- java - 如何检索 IoT 中心数据的属性,而不仅仅是实际有效负载
- kubernetes - 如何在 Kubernetes 中配置已经运行的集群
- google-maps - 如何在 vuetify 项目中使用本地文件获取自定义 gmap 图标
- python - 如何使用 tf.constant 或 numpy 数组初始化 tf.Variable?