1

我想ActiveRecord为 Salesforce 创建一个类似的界面,这样我就可以调用

class Account < Salesforce::Model

end

并且能够像Account.find_by_FirstName()使用我自己的method_missing函数一样调用方法。

但是,可以通过两种方式连接到 Salesforce:用户名和密码以及 oauth。如果使用用户名/密码,我可以在salesforce.yml文件中定义它并自动加载。但是使用 oauth,我不能这样做,因为每个用户都会定义这个。我不想用Account.new('oauth', oauth_parmas)or初始化一个类Account.new('username','password','sec_token'),而是让模型根据规则并通过查看其中一个或另一个是否存在来确定使用哪个。

有没有办法实现这个?换句话说,模型有没有办法知道当前用户是否有当前oauth令牌,或者是否定义了用户名/密码?

此外,如果我要在 Rails 应用程序中使用它,用户将在应用程序启动后登录,因此oauth令牌将在应用程序启动后定义,并且对于多个用户中的每个用户来说都是不同的。例如,假设我打电话Account.find_by_FirstName('John')AccountController#Show. 我希望 Account 模型oauth无需询问即可使用令牌或用户名/密码。我也不想直接在show控制器中的方法中建立连接。我有两个问题:

  1. 我将如何实现这一点?我应该before_filter在控制器中使用,还是有办法在整个应用程序范围内实现这个?
  2. 如果我有多个用户连接到 Salesforce,这会导致我的应用程序出现问题吗?换句话说,由于连接是动态的,我是否需要担心另一个用户正在使用连接?
4

1 回答 1

2

您的需要与建立连接没有什么不同ActiveRecord::Base:您使用连接建立连接,ActiveRecord::Base.establish_connection并且在连接建立后您使用的每个模型都知道要使用哪个连接,因为您在超类级别记住了连接。

对于 Salesforce,您可以使用相同的概念:

class Salesforce::Model
  def self.oauth_params
    @oauth_params
  end
  def self.establish_connection(oauth_params)
    @oauth_params = oauth_params
  end
  def self.find(id)
    # use oauth_params here 
  end
end

class Account < Salesforce::Model
end

现在你可以做类似的事情

Salesforce::Model.establish_connection ['username', 'password']
Account.find 2 # without specifying authentication params

由于您知道登录用户后知道身份验证参数,因此您可以在用户登录后建立连接:

def sign_user
  # user = ...
  oauth_params = get_oauth_params(user)
  Salesforce::Model.establish_connection(oauth_params)
end

并发(线程)

如果我有多个用户连接到 Salesforce,这会导致我的应用程序出现问题吗?换句话说,由于连接是动态的,我是否需要担心另一个用户正在使用连接?

合法的问题。如果您在线程环境中运行 Rails 应用程序(线程应用程序服务器 - fe Puma,多线程架构 - JRuby,Rubinius...)并且 Rails 配置为线程安全(config.threadsafe!),您可能会遇到并发问题(解释并不简单- 看看这个)。

如果这是您的情况,您可以将@oauth_params变量访问器限定为Thread.current

class Salesforce::Model

  @oauth_params = { Thread.current => nil }

  def self.oauth_params
    @oauth_params[Thread.current]
  end

  def self.establish_connection(oauth_params)
    @oauth_params[Thread.current] = oauth_params
  end

当前用户的线程是否有可能发生变化?

如果您执行的某些代码在新线程中运行,则有可能。铁:

Salesforce::Model.establish_connection(oauth_params)
Thread.new{ p Salesforce::Model.oauth_params }.join #=> puts nil

在这种情况下,您必须在新线程中重新建立连接(如果您需要,我可以这样做)。

我可以在线程 1 上请求某些内容并完成该请求,但之后,其他人使用线程 1,而我必须使用线程 2。这可能吗?

考虑一下,您需要在调用开始时重置变量,以避免下一个请求使用任何先前请求中设置的参数:

before_action :reset_connection, :sign_user

def reset_connection
  Salesforce::Model.establish_connection(nil)
end

def sign_user
  # ...
于 2013-09-26T13:59:25.990 回答