烘干Rails控制器

时间:2014-07-14 17:12:30

标签: ruby-on-rails ruby

我在Ruby / Rails中有一个应用程序,我必须连接到第三方应用程序(Xero会计)才能发送/提取数据。在整个应用程序中,这发生在几个控制器中。但是,虽然具体情况不同,但实际连接是相同的,如下所示:

require 'xero_gateway'
xero_config = YAML.load_file("#{Rails.root}/config/xero.yml")["testing"]
xero_private_key = "#{ENV['HOME']}/certs/breathehr_xero.key" || ENV["xero_private_key"]
xero_gateway = XeroGateway::PrivateApp.new(xero_config['consumer_key'], xero_config['consumer_secret'], xero_private_key)

代码的下一步可能是获取内容,例如发票,如:

xero_gateway.get_invoice('INV-001')

或者,在另一个控制器中,可能是创建联系人,例如:

xero_gateway.build_contact

在某处我可以放置连接代码,以便最终只能在每个特定控制器中调用xero_gateway吗?每次我必须进行身份验证和连接时,一次又一次地重复相同的代码是不正确的。

3 个答案:

答案 0 :(得分:1)

以@Dave Newton的答案为基础:

您将创建一个"提供商"将对象工厂与某些配置结合的类:

档案:lib/xero_gateway_provider.rb

require 'xero_gateway'

class XeroGatewayProvider
    cattr_accessor :default_private_key, :default_consumer_key, :default_consumer_secret

    def initialize(overrides = {})
        @private_key = overrides[:private_key] || self.class.default_private_key
        @consumer_key = overrides[:consumer_key] || self.class.default_consumer_key
        @consumer_secret = overrides[:consumer_secret] || self.class.default_consumer_secret
    end

    def create_private_app
        XeroGateway::PrivateApp.new(@consumer_key, @consumer_secret, @private_key)
    end
end

然后你可以创建一个Rails初始化器:config/initializers/xero_gateway_provider.rb

require 'xero_gateway_provider'
conf = YAML.load_file("#{Rails.root}/config/xero.yml")[Rails.env]
XeroGatewayProvider.default_private_key = "#{ENV['HOME']}/certs/breathehr_xero.key" || ENV["xero_private_key"]
XeroGatewayProvider.default_consumer_key = conf["consumer_key"]
XeroGatewayProvider.default_consumer_secret = conf["consumer_secret"]

使用它:

# Using default configs
provider = XeroGatewayProvider.new;
private_app = provider.create_private_app
private_app.get_invoice("...")

# Using overrides
provider = XeroGatewayProvider.new :consumer_key => '...', :consumer_secret => '...';
private_app = provider.create_private_app
private_app.get_invoice("...")

编辑:刚刚意识到如果它使用类级属性,则无需实例化XeroGatewayProvider,因此我将它们设为默认值,允许您单独配置每个提供程序。

另外@Gareth Burrows会评论放置和命名类的位置,我认为这在lib /目录中很合适。有关详细信息,请参阅帖子的编辑。

答案 1 :(得分:0)

您可以在名为Xero的models文件夹中创建常规ruby类,并在初始化程序中执行此代码。

require 'xero_gateway'
class Xero
  def initialize
    xero_config = YAML.load_file("#{Rails.root}/config/xero.yml")["testing"]
    xero_private_key = "#{ENV['HOME']}/certs/breathehr_xero.key" || ENV["xero_private_key"]
    xero_gateway = XeroGateway::PrivateApp.new(xero_config['consumer_key'],     xero_config['consumer_secret'], xero_private_key)
  end
end

然后打电话:

xero_gateway = Xero.new

另一种选择是在initializers /文件夹中创建初始化程序。 xero_gateway.rb

并将初始化代码放在那里。这样它只会在应用程序启动时解析。

答案 2 :(得分:0)

你可以把它放在任何地方,包括:

  1. 您的操作使用的实用程序类,或
  2. 基本动作类(meh)或
  3. 您的行动中包含的模块(meh)。
  4. 我倾向于实用类,因为:

    1. 很容易实例化或模拟/存根以进行测试,
    2. 它不会使您的动作类的表面区域更大