我已经弄明白了

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

我已经回答了一些问题:

  1. 如何让子域fu也与域一起工作?Here's someone that asked the same question,这就引出了this blog.
  2. What database, and how will it be structured?这是一个非常好的talk by Guy Naor,很好的question about PostgreSQL and schemas.
  3. 我已经知道我的模式都将具有相同的 struct .他们掌握的数据会有所不同.how can you run migrations for all schemas?这是an answer.

这三点涵盖了我需要知道的很多基本知识.然而,在接下来的步骤中,我似乎有很多实现方法.我希望有更好更简单的方法.

最后,回答我的问题

当新用户注册时,我可以轻松创建模式.然而,这里有一些问题/场景可能会给你一个更好的 idea .

  1. 我是否应该将其传递给shell script,将公共模式转储到临时模式中,并将其导入回我的主数据库(就像盖伊·内奥在视频中所说的那样)?这是quick summary/script I got from the helpful #postgres on freenode美元.虽然这可能会奏效,但我必须在Rails之外做很多事情,这让我有点不舒服..这也引出了下一个问题.
  2. Is there a way to do this straight from Ruby on Rails? 就像创建一个PostgreSQL模式一样,只需将Rails数据库模式(schema.rb——我知道,这很混乱)加载到该PostgreSQL模式中.
  3. Is there a gem/plugin that has these things already?种方法,比如"创建_pg _schema _和_加载_rails _schema(新的_schema _名称)".如果没有,我可能会制作一个,但我怀疑它在所有移动部件上的测试效果如何(尤其是如果我最终使用shell脚本创建和管理新的PostgreSQL模式).

谢谢,我希望不会太久!

推荐答案

Update Dec 5, 2011

多亏了布拉德·罗伯逊和他的团队,才有了Apartment gem强.这是非常有用的,可以做很多繁重的工作.

然而,如果你要修补模式,我强烈建议你知道它实际上是如何工作的.让自己熟悉Jerod Santo's walkthrough,这样你就会知道公寓Ruby 或多或少在做什么.

Update Aug 20, 2011 11:23 GMT+8

有人创造了一个blog post,并且很好地完成了整个过程.

Update May 11, 2010 11:26 GMT+8

从昨晚开始,我就能够找到一个方法来创建一个新的模式并加载模式.我喜欢它.不确定我所做的是否正确(到目前为止,似乎工作得很好),但至少离我更近了一步.如果有更好的办法,请告诉我.


  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相关问答推荐

如何将Form_With用于多个没有控制器的型号

如何从 Rails7.2 中的控制器获取名称空间?

Sidekiq with Rails - 控制台与 rake 任务中的不同 Sidekiq 实例

Ruby on Rails 更新触发了 Mailer 函数中的 ArgumentError

您如何查看在 Rails 中触发回调的关联模型?

Rails 4 中的 null_session 和 reset_session 有什么区别?

未初始化的常量 ActionDispatch::Session::EncryptedCookieStore (NameError)

如何在 Rails 中使用延迟作业(job)取消预定作业(job)?

如何在 Ruby on Rails 中创建一个锚点并重定向到这个特定的锚点

运行多个 Rails Server 实例

具有 has_many 关联的 FactoryGirl build_stubbed 策略

Rails:在 lib 目录中记录代码?

Ruby on Rails:有条件地显示部分

在 Controller 中调用模型方法

使用 Rails 时,在 Ruby 中处理常量的最佳方法是什么?

如何打印出范围之间的随机数?

设计/Rails - 如何删除特定的 Flash 消息? (登录成功)

简单的 rails rake 任务拒绝运行并出现错误不知道如何构建任务,为什么?

Ruby 中的类别名

在 Rails 3 中突出显示当前页面的最佳方法? -- 有条件地将css类应用于链接