Ram*_*yag 45 postgresql schema ruby-on-rails multi-tenant
我正在学习如何在Rails中创建一个多租户应用程序,该应用程序根据用于查看应用程序的域或子域来提供来自不同模式的数据.
我已经回答了一些问题:
这三点涵盖了我需要知道的许多一般内容.但是,在接下来的步骤中,我似乎有许多实现方法.我希望有更好,更简单的方法.
当新用户注册时,我可以轻松创建架构.但是,加载其余模式已有的结构的最佳和最简单的方法是什么?以下是一些可能为您提供更好主意的问题/方案.
谢谢,我希望不会太久!
Ram*_*yag 12
2011年12月5日更新
感谢Brad Robertson和他的团队,有了 Apartment gem.这是非常有用的,并做了很多繁重的工作.
但是,如果你要修改模式,我强烈建议你知道它是如何工作的.熟悉Jerod Santo的演练 ,这样你就会知道公寓宝石或多或少都在做什么.
更新2011年8月20日11:23 GMT + 8
有人创建了一篇博客文章,但整个过程非常顺利.
2010年5月11日更新格林威治标准时间11:26 + 8
从昨晚开始,我已经能够获得一种方法来创建一个新的模式并将schema.rb加载到其中.不确定我正在做的事情是否正确(到目前为止似乎工作正常),但至少距离更近了一步.如果有更好的方法请告诉我.
module SchemaUtils
def self.add_schema_to_path(schema)
conn = ActiveRecord::Base.connection
conn.execute "SET search_path TO #{schema}, #{conn.schema_search_path}"
end
def self.reset_search_path
conn = ActiveRecord::Base.connection
conn.execute "SET search_path TO #{conn.schema_search_path}"
end
def self.create_and_migrate_schema(schema_name)
conn = ActiveRecord::Base.connection
schemas = conn.select_values("select * from pg_namespace where nspname != 'information_schema' AND nspname NOT LIKE 'pg%'")
if schemas.include?(schema_name)
tables = conn.tables
Rails.logger.info "#{schema_name} exists already with these tables #{tables.inspect}"
else
Rails.logger.info "About to create #{schema_name}"
conn.execute "create schema #{schema_name}"
end
# Save the old search path so we can set it back at the end of this method
old_search_path = conn.schema_search_path
# Tried to set the search path like in the methods above (from Guy Naor)
# [METHOD 1]: conn.execute "SET search_path TO #{schema_name}"
# But the connection itself seems to remember the old search path.
# When Rails executes a schema it first asks if the table it will load in already exists and if :force => true.
# If both true, it will drop the table and then load it.
# The problem is that in the METHOD 1 way of setting things, ActiveRecord::Base.connection.schema_search_path still returns $user,public.
# That means that when Rails tries to load the schema, and asks if the tables exist, it searches for these tables in the public schema.
# See line 655 in Rails 2.3.5 activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
# That's why I kept running into this error of the table existing when it didn't (in the newly created schema).
# If used this way [METHOD 2], it works. ActiveRecord::Base.connection.schema_search_path returns the string we pass it.
conn.schema_search_path = schema_name
# Directly from databases.rake.
# In Rails 2.3.5 databases.rake can be found in railties/lib/tasks/databases.rake
file = "#{Rails.root}/db/schema.rb"
if File.exists?(file)
Rails.logger.info "About to load the schema #{file}"
load(file)
else
abort %{#{file} doesn't exist yet. It's possible that you just ran a migration!}
end
Rails.logger.info "About to set search path back to #{old_search_path}."
conn.schema_search_path = old_search_path
end
end
Run Code Online (Sandbox Code Playgroud)