我目前正在 Rails 中开发一个大型自定义内容管理解决方案,以处理许多不同的内容类型(模型)及其关系。
整个数据模型建立在活动记录之上,并具有内容导入和导出以及与其他服务同步等功能(例如移动同步将内容更改推送到智能手机)。
对于这些任务,我有许多数据对话,一方面是活动记录模型,另一方面是许多不同且已经存在的目标格式。
- JSON REST 服务反映模型层的变化
- RSS 提要发布新内容
- 导入/导出为专有 xml 格式
- ETC
对于新的数据格式,我可以自己定义结构,在大多数情况下,这意味着,让 rails 使用整洁的编组功能来处理它
format.html do
render 'show'
end
format.xml do
render xml: { content:@content }
end
format.json do
render json: { content:@content }
end
但是在必须提供现有数据模式的情况下,必须进行几个对话:
重命名键:在模型中,每个对象都由一个 id 属性标识,但在目标格式中,对象属性是名称 uid 或 OBJECT-ID ...
内联相关对象:假设我有一个名为 Person 的模型,它与 Address 模型相关。当使用 Rails xml 序列化时,地址对象将被省略或内联在标签下。在给定的目标格式中,地址可能必须内联在 Person 对象中,这意味着将包含以下输出
<person>
<name>Ben</name>
<street>Some Street</street>
<city>Berlin</city>
</person>
值转换: 可能需要日期属性作为 unix 时间戳而不是 utc 字符串
天真的解决方案:
所有这些转换都可以在需要时手动完成,这意味着只需放置一些创建目标数据结构的 ruby 代码:
data = {}
Person.all.each do |p|
# rename property
data[:guid] = p.id
data[:name] = p.full_name
# inline relation
data[:street] = p.primary_address.street
data[:city] = p.primary_address.locality
data[:member_since] = p.created_at.format(...)
end
render xml: { persons:data}
或者对于 xml,只能使用转换构建器模板。
虽然此选项可行且灵活,但它将对话逻辑传播到整个应用程序并使控制器增长,并且在大型应用程序中这将不利于可维护性......
我正在寻找的是基于模式的模型转换。这意味着我在某处定义了从我的 activerecord 模型到目标模式的映射(使用 ruby dsl,在 xml 中......),并且只要我需要某种数据格式,就必须执行模式对话:
data = Article.all
# the parameter is the name of the target schema
converter = ModelConversation.new(:legacy_contact_list)
render xml: { contacts: converter.execute(data) }
所以我真正在寻找的是类似于 xslt 但也适用于 json 输出并由 ruby 提供支持的东西。
您如何在 Rails 中进行数据对话的任何帮助/想法或故事将不胜感激。