在Rails中使用Decorator模式但无法访问视图助手

时间:2014-12-31 23:45:27

标签: ruby-on-rails ruby decorator

我正在尝试使用“Rails 4 Patterns”Code School课程中的学习来实现装饰器,但是我遇到了麻烦,因为我需要在Decorator类中使用视图助手。

我希望我的观点有:

<%= @model_decorator.previous %>

然后在装饰者:

def previous
  if object.prev_item.nil?
    "Previous"
  else
    link_to("Previous", object)
  end
end

本课程建议您在视图文件本身中调用视图助手中的装饰器,但如果逻辑可以输出一个带有助手的结果而没有助手输出一个结果,那就不好了。 (即需要输出是否为链接)。

我已尝试使用helpers.link_to,但由于未提供url_for选项的正确信息而导致错误。我已确认link_to("Previous", object)在视图中有效。

2 个答案:

答案 0 :(得分:3)

如果我理解你的问题,你基本上想要一个普通的老红宝石对象中的链接。

我的解决方案是:

include ActionView::Helpers::UrlHelper
link_to("Previous", Rails.application.routes.url_helpers.objects_path(object))
# assuming the object is always of one class 

如果对象属于不同的类,则可以使用.send方法将正确的消息发送到app,即:

include ActionView::Helpers::UrlHelper
link_to("Previous", Rails.application.routes.url_helpers.send("#{object.class}s_path".downcase.to_sym, object))
# I'd create a function out of that line to make it a bit neater

听起来url_for抛出的错误来自错过路线,并且有几种方法可以包含这些错误。我的解决方案有点使用Rails.application.routes.url_helpers来避免这个问题。希望这有帮助!

答案 1 :(得分:2)

对于Rails 4

include ActionView::Helpers::UrlHelper

link_to("Previous", Rails.application.routes.url_helpers.send("#{object.class.name.underscore}s_path".to_sym, object))

至于我,最好为它做一个装饰器:

class LinkDecorator
  include ActionView::Helpers::UrlHelper

  def initialize(label, object)
    @label  = label
    @object = object
  end

  def show
    link_to(label, url_helpers.send("#{object.class.name.underscore}s_path".to_sym, object))
  end

  def index
    link_to(label, url_helpers.send("#{object.class.name}s_path".to_sym))
  end

  ...

  private

  attr_reader :label, :object

  def url_helpers
    Rails.application.routes.url_helpers
  end
end

使用示例:

LinkDecorator.new(object.name, object).show