我知道我不想这样做,但我不知道我该怎么办呢。 我想根据哪个用户使用不同的数据库。所以我认为最好的方法是在第一次用户登录时设置会话变量...
这就是它的样子:
class Stuff < ActiveRecord::Base
establish_connection(
:adapter => "mysql2",
:host => "127.0.0.1",
:username => session["dbuser"],
:password => session["dbuserpass"],
:database => session["dbname"])
这当然不起作用。有谁知道如何做到这一点? 谢谢。
答案 0 :(得分: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,以便您没有如此暴露的凭据。你可以采取一个想法 从这个回答:
答案 1 :(得分:1)
您可以在模型中选择数据库,如下所示:
establish_connection "db_name_#{session[:something]}"
这样,您的模型就知道要拉/推数据的数据库。
看看这个:http://m.onkey.org/how-to-access-session-cookies-params-request-in-model
答案 2 :(得分:0)
正如kwon在原始问题的评论中暗示的那样,我会通过仅使用会话来保留用户的身份。然后,我将从模型中的逻辑和中央数据库(默认的rails DB)中提取所需的数据库连接,以保存用户详细信息和用户连接信息。
首先修改您的用户模型(假设您的用户有一个持久存储在中央数据库中的模型)
然后,您可以根据database.yml查找数据库连接。或者,如果每个用户有一个数据库,并且需要将其设置为动态数据库,请在用户模型上创建第二个模型(在中央数据库中),表示使用外键的数据库连接。
以下是一堆可能会或可能不会在现实中起作用的代码,但希望为您提供入门模板。
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
答案 3 :(得分:0)
如果您可以选择使用PostgreSQL,则可以使用PostgreSQL的Schemas功能为每个用户有效地拥有单独的表名称空间(模式)。这里的好处是你仍然连接到同一个数据库(从而避免乱砍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/
在这两个示例中,他们使用子域来在租户/架构之间切换,但您可以轻松地将其链接到用户记录。