如何在RoR中构造Util类

时间:2013-07-11 23:01:15

标签: ruby-on-rails ruby ruby-on-rails-3.2

我有一个用户可以上传的模板,可以生成报告。他们可以将特殊标签放入html模板中,它将替换为db中的数据。快速举例:

<div class="customer-info">
  <h1>{customer_name}</h1>
  <h2>{customer_address_line1}</h2>
  <h2>{customer_address_line2}</h2>
  <h2>{customer_address_city}, {customer_address_state} {customer_address_zip}</h2>
</div>

我有一个控制器,可以查找客户,然后解析模板并替换令牌。

现在我在控制器中创建了一个胖控制器的解析代码。不好。

但我应该在哪里移动代码?模特文件夹?创建一个Util文件夹并将其放在那里?

只是不确定Rails Way会是什么。

2 个答案:

答案 0 :(得分:1)

我对此也很好奇,发现了一个非常类似的讨论here。老实说,我认为这取决于解析代码的数量。如果只有很少的线,那么模型是一个安全的地方。如果它将是一个大包,特别是一个可重用的包,/ lib /文件夹可能是解析本身更好的选择。但是,您肯定应该如您所建议的那样将其从控制器中删除。

答案 1 :(得分:0)

我同意逻辑不应该在控制器中,但让我们得到一个 更具体地说明你将如何实现这一目标。

首先,您将模板存储在数据库中的哪个位置?他们 应该存储在他们自己的模型中,让我们称之为 CustomerTemplate并提供属性:Text类型的模板。

所以现在我们有两种类型的对象,Customer和 CustomerTemplates。如何为客户提供模板?它 老实说,只有一个render功能才能可怕 CustomerTemplate模型,它接受客户并呈现它,但是 它在您的应用程序中放置了一些不严格属于的逻辑 那里。你应该把“客户特定的渲染逻辑”分开 来自“渲染我简单的自定义模板语言”。

那么,让我们为您的自定义语言创建一个简单的模板处理程序, 我要昵称 Curly 。这个处理程序应该一无所知 顾客。它所做的只是取一个字符串并在其中插入值 {}的。这样,如果您希望将来添加新的模板类型 - 比如说,要像发票那样渲染另一个模型 - 你也可以使用相同的模型 模板类型。

Rails中的模板是响应call的类 在ActionView::Template注册。最简单的例子是Builder

这是一个快速编写的模板处理程序,它呈现了Curly。该 call函数返回一个eval'd的字符串,所以字符串必须 是有效的红宝石代码。由render调用确定的字符串eval,所以 它可以访问通过{ locals: {} }传入的任何变量 渲染选项。

# In lib/curly_template_handler.rb
class CurlyTemplateHandler
  def self.call(template)
    src = template.source
    """
    r = '#{src}'.gsub(/{([^}]*)}/) { |s|
       local_assigns[$1.to_sym] || s
    }
    raw r
"""
  end
end

确保处理程序已初始化,并让我们将其设置为侦听 :卷曲类型。

# In config/initializers/register_curly_template.rb
ActionView::Template.register_template_handler(:curly, CurlyTemplateHandler)

我们需要将lib /添加到autoload_paths以便加载类:

# config/application.rb
config.autoload_paths += %W(#{config.root}/lib)

最后,我们可以在视图中渲染我们的模板!我在这里嵌入字符串,但你真的从CustomerTemplate对象中获取它:

<%= render(inline: "<h2>{customer_name}</h2><p>{customer_address}</p>",
           type: :curly,
           locals: { customer_name: @customer.name,
           customer_address: @customer.address }) %>

不要在生产中使用我的示例代码!我遗漏了一堆角落 您需要处理的案例,例如清理用户输入。