我同意逻辑不应该在控制器中,但是让我们得到一个
更具体地说明您将如何实现这一点。
首先,您将模板存储在数据库中的什么位置?他们
应该存储在自己的模型中,我们称之为
CustomerTemplate 并给出一个 Text 类型的 :template 属性。
所以现在我们有两种类型的对象,客户和
客户模板。如何在给定模板的情况下呈现客户?它
老实说,只有一个 render 函数不会可怕
CustomerTemplate 模型,它接受一个客户并呈现它,但是
它在您的应用程序中放置了一些不严格属于的逻辑
那里。您应该分离出“客户特定的渲染逻辑”
来自“渲染我的简单自定义模板语言”。
所以,让我们为您的自定义语言创建一个简单的模板处理程序,
我将给它起个昵称 Curly。这个处理程序应该一无所知
顾客。它所做的只是接受一个字符串并在里面插入值
{} 的。这样,如果您想在将来添加新的模板类型 -
比如说,渲染另一个模型,比如发票——你可以使用相同的
模板类型。
Rails 中的模板是响应call 的类,并且是
注册ActionView::Template。最简单的例子是Builder。
这是一个快速编写的模板处理程序,它呈现 Curly。这
call 函数返回一个经过评估的字符串,因此该字符串必须
是有效的红宝石代码。由渲染调用限定的字符串 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
确保处理程序已初始化,让我们将其设置为侦听
:curly 类型。
# 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 }) %>
不要在生产中使用我的示例代码!我遗漏了一堆角落
您需要处理的情况,例如清理用户输入。