Ruby on rails 如何在RoR中构造Util类
我有一个模板,用户可以上传生成报告。他们可以将特殊的标记放入html模板中,然后用数据库中的数据替换。快速示例:Ruby on rails 如何在RoR中构造Util类,ruby-on-rails,ruby,ruby-on-rails-3.2,Ruby On Rails,Ruby,Ruby On Rails 3.2,我有一个模板,用户可以上传生成报告。他们可以将特殊的标记放入html模板中,然后用数据库中的数据替换。快速示例: <div class="customer-info"> <h1>{customer_name}</h1> <h2>{customer_address_line1}</h2> <h2>{customer_address_line2}</h2> <h2>{customer_ad
<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>
{客户名称}
{客户\地址\线路1}
{客户\地址\线路2}
{客户地址{城市},{客户地址{州}{客户地址}
我有一个控制器,它查找客户,然后解析模板并替换令牌
现在我在创建fat控制器的控制器中有了解析代码。不太好
但是我应该把代码移到哪里呢?模型文件夹?创建一个Util文件夹并将其放在那里
只是不确定Rails的方式会是什么。我对此也很好奇,并发现了一个非常类似的讨论。老实说,我认为这取决于有多少解析代码。如果只有很少几行,那么模型就是一个安全的地方。如果它是一个大的包,特别是一个可重用的包,/lib/文件夹可能是解析本身的更好选择。但是,正如您所建议的,您肯定应该将其从控制器中删除 我同意逻辑不应该在控制器中,但是让我们来看看 关于如何实现这一点,请再具体一点 首先,您将模板存储在数据库中的什么位置?他们 应该存储在自己的模型中,我们称之为
CustomerTemplate
并提供一个属性:文本类型的模板
现在我们有两种类型的对象,客户和
客户模板。如何呈现给定模板的客户?信息技术
老实说,在中只使用render
函数并不可怕
接受客户并对其进行渲染的CustomerTemplate模型,但是
它是在你的应用程序中加入一些逻辑,而这些逻辑并不严格属于你的应用程序
那里您应该分离出“特定于客户的呈现逻辑”
来自“呈现我的简单自定义模板语言”
那么,让我们为您的自定义语言创建一个简单的模板处理程序,
我要给它起个绰号叫“卷发”。这个处理程序不应该知道任何关于
客户。它所做的只是获取一个字符串并在其中插入值
{}的。如果将来要添加新模板类型,请使用这种方法-
比方说,要渲染另一个模型(如发票),可以使用相同的
模板类型
Rails中的模板是响应调用的类
在……登记。最简单的例子是
下面是一个快速编写的模板处理程序,它可以渲染Curly。这个
call
函数返回一个已求值的字符串,因此该字符串必须
必须是有效的ruby代码。字符串eval的作用域由render调用确定,因此
它可以访问通过{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/添加到自动加载路径,以便加载类:
# 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 }) %>
不要在生产中使用我的示例代码我漏掉了一堆角
您需要处理的情况,如清理用户输入。lib
文件夹是您需要放置它的地方。这不是model
代码,因为您没有将其存储在数据库中。(lib的另一种选择是创建一个app/services
文件夹,该文件夹也适用于此场景)我假设它将位于客户模型中,而不是它自己的模型。类似于:def self.parse(html)的东西客户模型不是正确的位置。更有意义的是:customer.parse_模板
或customer.address
?在客户模型中解析的模板违反了单一责任原则,并且(如前所述)最好移动到服务
或库
对象中。