roo*_*m13 5 ruby ruby-on-rails data-conversion
我目前正在开发一个大型的自定义内容管理解决方案,以处理许多不同的内容类型(模型)及其关系.
整个数据模型建立在活动记录之上,具有内容导入和导出以及与其他服务同步的功能(例如,将内容更改推送到智能手机的移动同步).
对于这些任务,我有许多数据对话,一方面是活动记录模型,另一方面是许多不同的和已经存在的目标格式.
对于新的数据格式,我可以自己定义结构,在大多数情况下意味着,让rails通过使用整洁的编组功能来处理它
format.html do
render 'show'
end
format.xml do
render xml: { content:@content }
end
format.json do
render json: { content:@content }
end
Run Code Online (Sandbox Code Playgroud)
但是,在必须提供现有数据模式的情况下,必须进行多次对话:
重命名键:在模型中,每个对象都由id属性标识,但在目标格式中,objects属性是名称uid或OBJECT-ID ...
内联相关对象:鉴于我有一个名为Person的模型,它与Address模型相关.使用Rails xml序列化时,地址对象将被省略或在标签下内联.在给定的目标格式中,地址可能必须在Person对象中内联,这意味着以下输出将是nedded
<person>
<name>Ben</name>
<street>Some Street</street>
<city>Berlin</city>
</person>
Run Code Online (Sandbox Code Playgroud)
值转换: 可能需要日期属性作为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}
Run Code Online (Sandbox Code Playgroud)
或者,对于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) }
Run Code Online (Sandbox Code Playgroud)
所以我实际上寻找的东西类似于xslt,但也适用于json输出并由ruby提供支持.
任何有关如何在rails中进行数据对话的帮助/想法或故事都将受到赞赏.
我编写 XSLT 转换已有几年了,我只能建议不要使用 XSLT 或“类似的东西”。
既然您有 Ruby 应用程序,就使用 Ruby 吧!我认为它已经满足您的需求了。
关于您关心的问题:
虽然此选项是可行且灵活的,但它将对话逻辑传播到整个应用程序并使控制器增长,并且在大型应用程序中这将不利于可维护性......
这将在您的控制之下。只需将转换器视为应用程序的任何其他部分即可,并保持较高的代码质量。如果您将转换逻辑放入模型本身或将其移动到库中,您的控制器将不会增长。重构您的转换器以保持简洁。
看看你的“天真的”例子
# 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(...)
Run Code Online (Sandbox Code Playgroud)
这段代码基本上表示,在您的目标格式中,id被调用guid,full_name被调用name等等。我怀疑你能写得比你已经给出的代码短得多。所以我认为这里不需要其他技术。
| 归档时间: |
|
| 查看次数: |
272 次 |
| 最近记录: |