gpt4 book ai didi

ruby-on-rails - 使用 PostgreSQL 的模式和 Rails 创建 Multi-Tenancy 应用程序

转载 作者:行者123 更新时间:2023-11-29 11:06:15 25 4
gpt4 key购买 nike

我已经想到的东西

我正在学习如何在 Rails 中创建一个 Multi-Tenancy 应用程序,该应用程序根据用于查看应用程序的域或子域提供来自不同模式的数据。

我已经回答了一些问题:

  1. 如何让 subdomain-fu 也能与域一起工作? Here's someone that asked the same question这会引导你到 this blog .
  2. 什么数据库,它的结构如何?这里有一个很好的 talk by Guy Naor ,很好question about PostgreSQL and schemas .
  3. 我已经知道我的模式都将具有相同的结构。它们所持有的数据会有所不同。那么,如何为所有模式运行迁移?这里是 an answer .

这三点涵盖了很多我需要知道的一般知识。但是,在接下来的步骤中,我似乎有很多实现方法。我希望有更好、更简单的方法。

最后,关于我的问题

当新用户注册时,我可以轻松创建架构。但是,加载其余模式已有的结构的最佳和最简单方法是什么?以下是一些问题/场景,可能会给您一个更好的主意。

  1. 我是否应该将它传递给一个shell 脚本,将公共(public)模式转储到一个临时模式中,然后将其导入回我的主数据库(很像 Guy Naor 在他的视频中所说的)?这是一个 quick summary/script I got from the helpful #postgres on freenode .虽然这可能会奏效,但我将不得不在 Rails 之外做很多事情,这让我有点不舒服......这也让我想到了下一个问题。
  2. 有没有办法直接从 Ruby on Rails 执行此操作?就像创建一个 PostgreSQL 模式,然后只需将 Rails 数据库模式(schema.rb - 我知道,这很困惑)加载到该 PostgreSQL 模式中。
  3. 是否有 gem/插件已经具备这些功能? 方法如“create_pg_schema_and_load_rails_schema(the_new_schema_name)”。如果没有,我可能会努力制作一个,但我怀疑所有移动部件的测试效果如何(特别是如果我最终使用 shell 脚本来创建和管理新的 PostgreSQL 模式)。

谢谢,我希望不会太长!

最佳答案

2011 年 12 月 5 日更新

感谢 Brad Robertson 和他的团队,这就是 Apartment gem .它非常有用,可以完成很多繁重的工作。

但是,如果您要修改模式,我强烈建议您了解它的实际工作原理。熟悉 Jerod Santo's walkthrough ,这样您就会知道 Apartment gem 或多或少在做什么。

更新于 2011 年 8 月 20 日 11:23 GMT+8

有人创建了一个 blog post并很好地完成了整个过程。

2010 年 5 月 11 日 11:26 GMT+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

关于ruby-on-rails - 使用 PostgreSQL 的模式和 Rails 创建 Multi-Tenancy 应用程序,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2782758/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com