0

カスタム疑似 API のような、サードパーティのサイトと通信するためにいくつかの Ruby クラスを必要とする Rails アプリケーションを作成しています。このコードを Rails/MVC パラダイムに最適に適合させる方法を理解するのに苦労しています。また、サードパーティのサイトが変更された場合に必要な変更を最小限に抑えるために、このコードをアプリの残りの部分から分離したいと考えています。

私の最初の試みは、 と呼ばれる非アクティブレコード モデルに通信コードをSearch配置し、アプリケーションの各データベース モデル (DataModel1およびDataModel2) にメソッドを追加して、データをサード パーティ サイトの適切な形式に変換することでした。サード パーティのサイトの形式が変更された場合、すべてのモデルを変更する必要があるため、これは好きではありません。

理想的にSearchは、データベース モデルのそれぞれに対応するいくつかの独立したデータ型クラスを持つモデルを用意し、そのデータをSearchモデルに必要な適切な形式に変換したいと考えています。基本的にに対応し、に対応DataType1するクラスです。 DataModel1DataType2DataModel2

たぶん私はこれを考えすぎていますが、どこDataType1にクラスを配置しますか(理想的にはモデルDataType2に関連付けられた場所)? Searchこのコードを整理するより良い方法はありますか?

4

1 に答える 1

0

多くの実験と読書の後、誰かが興味を持っている場合に備えて、私が最終的に得たものは次のとおりです。

検索モデルとサブモデルで表されるすべてのデータと、lib フォルダー内のモジュール内のサード パーティ サイトの接続クライアントを使用するハイブリッド アプローチを採用することになりました。

モデル/search.rb:

class Search    
  def initialize( params )
    # code to start a new Search on third party site
    @result = SearchApi.example_query( data_type_1_param )
    # more code...
  end
  # other code to assist in parsing of search results
end

モデル/検索/data_type_1.rb:

class Search::DataType1 < Hash 
  def initialize( DataModel1 )
    # code to convert DataModel1 to DataType1 for sending request
  end
end

DataType1 に似た他の検索サブモデルもいくつかあります。さらに、検索サブモデルを作成して、検索によって返されたデータを表現し、プログラムでの使用を容易にし、抽象化のレイヤーを持たせました。

models/search/results.rb:

class Search::Results
  def initialize(result_hash)
    @data = result_hash
  end

  def field_1
    # code to parse and display field 1 from @data hash
  end

  def field_2
    # code to parse and display field 2 from @data hash
  end
  #.... etc
end

検索モデル自体は完全に必要というわけではありませんが (ほとんどのコードはモジュールとサブモデルにあります)、検索を作成して表示するための MVC フレームワークにうまく適合します。

最後に、クライアント クラスを含むモジュールを作成して、実際にサード パーティのサイトにアクセスし、検索を実行しました。これを検索モデルに含めることはできたかもしれませんが、検索モデルはクエリごとに再作成されますが、このクライアントは (さまざまな理由で) 存続し、複数の検索を処理する必要がありました。

lib/search_api.rb:

require 'search_api/client'

module SearchApi 
  class << self
    def client
      @client ||= SearchApi::Client.new()
      @client
    end

    def example_query( data )
      results = client.query( formatted_data )
      # among other code
    end
    # other code to perform validations and interact with client
  end
end

lib/search_api/client.rb:

module SearchApi
  class Client
    include HTTParty

    # code to create and handle connection to Search site
  end
end

この方法は、すべてのベスト プラクティスに従っているわけではなく、おそらく多くの状況ではやり過ぎかもしれませんが、私が取り組もうとしていた問題にはうまく機能しているように見えました。誰かがリファクタリングするためのより良いアイデアを持っているなら、私はすべて耳にします。

于 2013-05-13T02:32:47.500 に答える