dceballos / roomer Goto Github PK
View Code? Open in Web Editor NEWRoomer is a Multitenant framework for Rails using PostgreSQL
Home Page: https://github.com/dceballos/roomer
License: MIT License
Roomer is a Multitenant framework for Rails using PostgreSQL
Home Page: https://github.com/dceballos/roomer
License: MIT License
Given shared table foo
,
add_index(:foo,:bar)
creates an index called global."index_global.foo_on_bar"
(with the quotes).remove_index(:foo,:bar)
tries to remove an index called index_global.global.foo_on_bar
.ideally should compare the migration version be regenerating shared_schema.rb
I added a new table (and model) along with a unique index to the tenanted schema via rake roomer:tenanted:migrate and all went well. However, if after the migration, when I issue Tenant.create it fails with the following error:
-- add_index("corporate_advertisers", ["company_id"], {:name=>"company_id", :unique=>true})
ActiveRecord::StatementInvalid: PGError: ERROR: relation "company_id" already exists
: CREATE UNIQUE INDEX "company_id" ON "poindexter"."corporate_advertisers" ("company_id")
The problem appears to be due to inconsistencies in the output of the schema creation when done via tenant record creation, specifically the generated name of the index.
via migrate:
CREATE UNIQUE INDEX "index_wendy.corporate_advertisers_on_company_id" ON "wendy"."corporate_advertisers" ("company_id")
via Tenant.create!:
CREATE UNIQUE INDEX "company_id" ON "poindexter"."corporate_advertisers" ("company_id")
In a given postgres namespace (schema) you can not have two indexes with the same name, and as it happens when the schema is created via the Tenant.create two of different add_index statements are resolving to the same name, they are:
add_index "addresses", ["company_id", "name"], :name => "company_id", :unique => true
add_index :corporate_advertisers, :company_id, :unique => true
For whatever reason the index name generated by Tenant.create is way different from the one generated via migrate. I also noticed that if I rollback the migration, then change the add_index statement in the migration file to:
add_index :corporate_advertisers, :company_id, :unique => true, :name => 'corporate_advertisers_company_id'
Then run the migration, the index name is created as specified above. However, Tenant.create will still try and create the index with the name 'company_id' and ignores the :name option.
After doing a bit of digging, I noticed that in the /schemas/tenanted_schema.rb file the add_index statement listed as:
add_index "corporate_advertisers", ["company_id"], :name => "company_id", :unique => true
event though I explicitly specified the :name option in the migration file. I did find that I can manually change the :name option in tenanted_schema.rb to match what was in the migration rb and that temporarily fixes the problem, but that change gets overwritten whenever I run a migration.
Migration Generator methods
if I create a tenant.. Tenant.create(:url_identifier => "SomePlace.lvh.me", :schema_name = "SomePlace")
Then attempt to navigate via a browser to the app using http://SomePlace.lvh.me:3000/
An error is returned via Roomer...
No tenant found for 'someplace.lvh.me' url identifier
This is due to the method current_tenant defined in lib/roomer/extensions/controller.rb and case-sensitive comparisons in the postgresSQL database
def current_tenant
@current_tenant ||= Roomer.tenant_model.find_by_url_identifier(url_identifier)
end
Because postgres uses case sensitive string comparision and the url is stored in the database with mixed case while the url returned by request.host is lowercase the tenant record is not found.
The table_name_prefix
configured by roomer isn't used by AR's reset_table_name
when set_table_name
has been called. Models that use set_table_name
end up not having a schema.
This breaks doorkeeper, at least. I haven't tested a non-engine model to see if it would suffer from the same problem.
PGError: ERROR: relation "schema_migrations" does not exist
LINE 4: WHERE a.attrelid = '"schema_migrations"'::regcl...
^
: SELECT a.attname, format_type(a.atttypid, a.atttypmod), d.adsrc, a.attnotnull
FROM pg_attribute a LEFT JOIN pg_attrdef d
ON a.attrelid = d.adrelid AND a.attnum = d.adnum
WHERE a.attrelid = '"schema_migrations"'::regclass
AND a.attnum > 0 AND NOT a.attisdropped
ORDER BY a.attnum
Tasks: TOP => db:seed => db:abort_if_pending_migrations
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.