0

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

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

理想情况下,我希望有一个Search具有多个独立数据类型类的模型,这些类对应于我的每个数据库模型,并将数据转换为Search模型所需的适当格式。基本上是一个对应于 的DataType1DataModel1,并且DataType2对应于DataModel2

也许我想太多了,但是我会把类放在哪里DataType1DataType2最好是与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 的搜索子模型。此外,我创建了 Search 子模型来表示 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 框架。

最后,我创建了一个带有客户端类的模块来实际联系第三方站点并进行搜索。虽然我可能已经能够将它包含在 Search 模型中,但我需要这个客户端保持(出于多种原因)并处理多个搜索,同时为每个查询重新创建 Search 模型。

库/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 回答