在Rails应用程序中放置隔离类的约定

时间:2013-05-04 04:26:17

标签: ruby-on-rails model abstraction

我正在编写一个Rails应用程序,它需要一些Ruby类与第三方站点进行通信,有点像自定义伪API。我无法弄清楚如何最好地将此代码融入Rails / MVC范例。我还想尝试将此代码与我的应用程序的其余部分隔离,以最大限度地减少第三方网站更改时所需的更改。

我最初的尝试是将通信代码放在一个名为Search的非主动记录模型中,然后为我的每个应用程序的数据库模型(DataModel1DataModel2)添加一个方法来转换数据到第三方网站的相应表格。我不喜欢这样,因为如果第三方网站的格式发生变化,我需要更改我的所有模型。

理想情况下,我希望拥有一个Search模型,其中包含几个与我的每个数据库模型相对应的独立数据类型,并将数据转换为Search模型所需的适当格式。基本上是DataType1类,对应DataModel1DataType2对应DataModel2

也许我在想这个,但是我会在哪里放DataType1DataType2类(理想情况下与Search模型关联的地方)?有没有更好的方法来组织这段代码?

1 个答案:

答案 0 :(得分: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的搜索子模型。 此外,我创建了搜索子模型来表示搜索返回的数据,以便在程序中使用,并具有一个抽象层。

<强>模型/搜索/ 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

这种方法可能不会遵循所有最佳实践,并且在很多情况下可能有点过分,但似乎对我试图解决的问题很有效。如果有人有更好的重构思路,我会全力以赴。