私は現在、さまざまなコンテンツタイプ(モデル)とそれらの関係を処理するために、Railsで大規模なカスタムコンテンツ管理ソリューションを開発しています。
データモデル全体はアクティブレコードに基づいて構築されており、コンテンツのインポートとエクスポートに加えて、他のサービスとの同期(たとえば、コンテンツの変更をスマートフォンにプッシュするモバイル同期)などの機能があります。
これらのタスクでは、多くのデータ会話があります。つまり、一方はアクティブなレコードモデルであり、もう一方は多くの異なる既存のターゲット形式です。
- モデルレイヤーの変更を反映するJSONRESTサービス
- 新しいコンテンツを公開するためのRSSフィード
- 独自のxml形式へのインポート/エクスポート
- 等
新しいデータ形式の場合、自分で構造を定義できます。ほとんどの場合、きちんとしたマーシャリング機能を使用して、レールに構造を処理させます。
format.html do
render 'show'
end
format.xml do
render xml: { content:@content }
end
format.json do
render json: { content:@content }
end
ただし、既存のデータスキーマを提供する必要がある場合は、いくつかの会話を行う必要があります。
キーの名前変更:モデルでは、すべてのオブジェクトはidプロパティで識別されますが、ターゲット形式では、objectsプロパティの名前はuidまたはOBJECT-IDです。
関連するオブジェクトのインライン化:住所モデルに関連するPersonというモデルがあるとします。Rails xmlシリアル化を使用する場合、アドレスオブジェクトは省略されるか、タグの下にインライン化されます。特定のターゲットフォーマットでは、アドレスはPersonオブジェクトでインラインである必要がある場合があります。つまり、次の出力が必要になります。
<person>
<name>Ben</name>
<street>Some Street</street>
<city>Berlin</city>
</person>
値の変換: 日付プロパティは、UTC文字列ではなくUNIXタイムスタンプとして必要になる場合があります
素朴な解決策:
このすべての変換は、必要なときにいつでも手動で実行できます。つまり、ターゲットデータ構造を作成するルビーコードを配置するだけです。
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でデータ会話を行う方法についてのヘルプ/アイデアやストーリーをいただければ幸いです。