1

ActiveRecordを呼び出せるように、Salesforce 用の のようなインターフェースを作成したい

class Account < Salesforce::Model

end

Account.find_by_FirstName()自分の関数を使用するようなメソッドを呼び出すことができmethod_missingます。

ただし、Salesforce への接続は、ユーザー名とパスワード、および oauth の 2 つの方法で行うことができます。ユーザー名/パスワードが使用されている場合は、ファイルに定義してsalesforce.yml自動的にロードできます。しかし、oauth では、各ユーザーがこれを定義するため、それを行うことはできません。Account.new('oauth', oauth_parmas)またはでクラスを初期化したくありませんAccount.new('username','password','sec_token')が、ルールに基づいてどちらを使用するかをモデルに決定させ、どちらかが存在するかどうかを確認します。

これを実装する方法はありますか?言い換えれば、現在のユーザーが現在のoauthトークンを持っているかどうか、またはユーザー名/パスワードが定義されているかどうかをモデルが知る方法はありますか?

さらに、これを Rails アプリで使用する場合、ユーザーはアプリの起動後にログインするため、oauthトークンはアプリケーションの起動後に定義され、複数のユーザーごとに異なります。たとえば、私が を呼び出したとAccount.find_by_FirstName('John')AccountController#Showます。Account モデルで、oauth尋ねられることなくトークンまたはユーザー名/パスワードを使用するようにします。showまた、コントローラーのメソッドで直接接続を確立したくありません。2 つの質問があります。

  1. これをどのように実装しますか?コントローラーでa を使用する必要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 に答える