5

私は現在、さまざまなコンテンツタイプ(モデル)とそれらの関係を処理するために、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でデータ会話を行う方法についてのヘルプ/アイデアやストーリーをいただければ幸いです。

4

1 に答える 1

2

私は数年間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(...)

このコードは基本的に、ターゲット形式で、idと呼ばれるguidfull_nameと呼ばれる、などと言っていますname。すでに与えたコードよりもはるかに短く書くことができるとは思えません。したがって、ここでは別のテクノロジーの必要性はわかりません。

于 2012-12-20T16:02:50.670 に答える