Using multiple PostgreSQL schemas with Rails models

26,997

Solution 1

PostgreSQL adapter schema_search_path in database.yml does solve your problem?

development:
  adapter: postgresql
  encoding: utf-8
  database: solidus
  host: 127.0.0.1
  port: 5432
  username: postgres
  password: postgres
  schema_search_path: "discogs,public"

Or, you can to specify different connections for each schema:

public_schema:
  adapter: postgresql
  encoding: utf-8
  database: solidus
  host: 127.0.0.1
  port: 5432
  username: postgres
  password: postgres
  schema_search_path: "public"

discogs_schema:
  adapter: postgresql
  encoding: utf-8
  database: solidus
  host: 127.0.0.1
  port: 5432
  username: postgres
  password: postgres
  schema_search_path: "discogs"

After each connection defined, create two models:

class PublicSchema < ActiveRecord::Base
  self.abstract_class = true
  establish_connection :public_schema
end

class DiscoGsSchema < ActiveRecord::Base
  self.abstract_class = true
  establish_connection :discogs_schema
end

And, all your models inherit from the respective schema:

class MyModelFromPublic < PublicSchema
  set_table_name :my_table_name
end

class MyOtherModelFromDiscoGs < DiscoGsSchema
  set_table_name :disco
end

I hope it helps.

Solution 2

The correct one for rails 4.2 is as:

class Foo < ActiveRecord::Base
  self.table_name = 'myschema.foo'
end

More info -http://api.rubyonrails.org/classes/ActiveRecord/ModelSchema/ClassMethods.html#method-i-table_name-3D

Solution 3

In migrations:

class CreateUsers < ActiveRecord::Migration
  def up
    execute 'CREATE SCHEMA settings'
    create_table 'settings.users' do |t|
      t.string :username
      t.string :email
      t.string :password

      t.timestamps null: false
    end
  end

  def down
    drop_table 'settings.users'
    execute 'DROP SCHEMA settings'
  end

end

Optional in model

class User < ActiveRecord::Base
  self.table_name 'settings.users'
end

Solution 4

Just do

class Foo < ActiveRecord::Base
  self.table_name = 'myschema.foo'
end

Solution 5

Because set_table_name was removed, and it was replaced by self.table_name.

I think you should code follow as:

class Foo < ActiveRecord::Base
  self.table_name =  'myschema.foo'
end
Share:
26,997
Johan
Author by

Johan

Updated on September 06, 2020

Comments

  • Johan
    Johan over 3 years

    I have a PostgreSQL database for my Rails application. In the schema named 'public' the main Rails models tables are stored etc. I have created a 'discogs' schema which will have tables with names that are sometimes the same as in the 'public' schema - which is one of the reasons that I'm using schemas to organize this.

    How would I setup models from the 'discogs' schema in my app? I will be using Sunspot to let Solr index these models as well. I'm unsure of how you would do this.

  • Ivan Velichko
    Ivan Velichko over 10 years
    Looks like you should add self.abstract_class = true to *Schema classes to avoid non-existing tables troubles.
  • Edgar Ortega
    Edgar Ortega over 4 years
    Deprecate set_table_name in favour of self.table_name= github.com/rails/rails/commit/0b72a04
  • Foton
    Foton about 4 years
    The config schema_search_path: is crucial, if You leave it and use only self.table_name = 'discogs.disco' than all seems to work...except database_cleaner. It uses schema_search_path for to get list of tables from schemas. I ommit this and records keep stocking in ommited schema tables between test runs.