4

私はこれを行うことを想定していないことを知っていますが、他にどのようにこれを行うべきかわかりません。ログインしたユーザーに基づいて異なるデータベースを使用したいので、最初のユーザーログイン時にセッション変数を設定するのが最善の方法だと思いました...

これはどのように見えるかです:

class Stuff < ActiveRecord::Base
    establish_connection(
        :adapter  => "mysql2",
        :host     => "127.0.0.1",
        :username => session["dbuser"],
        :password => session["dbuserpass"],
        :database => session["dbname"])

もちろん、これは機能しません。誰かがこれを行う方法を知っていますか?ありがとうございました。

4

4 に答える 4

3

メソッドを次のように書き換えることができます。

class Stuff < ActiveRecord::Base
 def establish_connection_user(user, pass, database)
   establish_connection(
    :adapter  => "mysql2",
    :host     => "127.0.0.1",
    :username => user,
    :password => pass,
    :database => database)
  end
end

そしてあなたのコントローラーで:

  class StuffController < ApplicationController
    def login #example 
      stuff = Stuff.new
      stuff.establish_connection_user(
        session[:dbuser], 
        session[:dbuserpass],
        session[:dbname]) 
    end

このようにして、それをカプセル化し、詳細を目立たなくします。資格情報が公開されないように、Cookie も暗号化することをお勧めします。この回答からアイデアを得ることができます:

Rails で暗号化された Cookie を保存する

于 2013-02-19T15:22:34.750 に答える
1

次のように、モデルでデータベースを選択できます。

establish_connection "db_name_#{session[:something]}"

このようにして、モデルはデータをプル/プッシュするデータベースを認識します。

これを見てください: http://m.onkey.org/how-to-access-session-cookies-params-request-in-model

于 2013-02-05T00:42:42.253 に答える
0

PostgreSQL を使用するオプションがある場合は、PostgreSQL のスキーマ機能を使用して、ユーザーごとに個別のテーブル名前空間 (スキーマ) を効果的に持つことができます。ここでの利点は、引き続き同じデータベースに接続していることです (したがって、Rails API のハッキングを回避できます) が、データベースの分離という点では、複数の DB と同じ利点が得られます。

RailsCasts Pro サブスクリプション (月額 $9) をお持ちの場合、Ryan Bates がこの件に関する優れたビデオを公開しています: http://railscasts.com/episodes/389-multitenancy-with-postgresql

Jerod Santo も彼のブログで素晴らしい記事を書いています: http://blog.jerodsanto.net/2011/07/building-multi-tenant-rails-apps-with-postgresql-schemas/

どちらの例でも、サブドメインを使用してテナント/スキーマを切り替えていますが、ユーザー レコードに簡単にリンクできます。

于 2013-02-23T20:11:55.420 に答える
0

元の質問のコメントで kwon が示唆しているように、ユーザーの ID を保持するためだけにセッションを使用してアプローチします。次に、モデル内のロジックと、ユーザーの詳細とユーザー接続情報を保持する中央データベース (デフォルトの Rails DB) から目的のデータベース接続を取得します。

ユーザー モデルの変更から始めます (ユーザーが中央データベースに保持されているモデルを持っていると仮定します)。

  • 使用するデータを表す属性をユーザーに追加します
  • アプリケーションコントローラーで、セッションキーに基づいて before_filter でユーザーを設定します
  • ユーザー引数で Stuff モデルを初期化します

その後、database.yml に基づいてデータベース接続を検索できます。または、ユーザーごとに 1 つのデータベースがあり、これを動的にする必要がある場合は、ユーザー モデルへの外部キーを使用してデータベース接続を表す 2 つ目のモデル (中央データベース内) を作成します。

以下は、実際には機能する場合と機能しない場合がある一連のコードですが、うまくいけば、開始するためのテンプレートが得られます。

class ApplicationController < ActionController::Base
  before_filter :set_user

  def set_user
    begin
      @user = UserProfile.find(session[:usernumber]) if session[:usernumber]        
    rescue
      logger.warn "Possible error in set_user. Resetting session: #{$!}"
      @user=nil
      session[:usernumber]=nil
      reset_session
    end
  end

end

class StuffController < ApplicationController
  def show
    @stuff = Stuff.user_get(@user, params[:id])
  end
end

class Stuff < ActiveRecord::Base
  # This would be better moved to a module to reuse across models
  def self.establish_connection_user(user)
    establish_connection(user.connection_hash)
  end
  def establish_connection_user(user)
    establish_connection(user.connection_hash)
  end

  def self.user_get user, item_id        
    establish_connection_user(user)
    find(id)
  end

  def self.user_where user, *query_args        
    establish_connection_user(user)
    where(query_args)
  end
  # Even better than replicating 'where', create model methods 
  # that are more representative of your desired functionality
end

class User  < ActiveRecord::Base
  has_one :user_connection
  def connection_hash
    uc = self.user_connection
    {:database=>uc.db, :password=>uc.pass, :user=>uc.username, :host=>uc.dbhost, :adapter=>uc.adapter}
  end
  # User probably contains other user-facing details
end
于 2013-02-19T19:30:00.010 に答える