I've built a single tenant rails application with all core features ready to ship. But I now want to make it multi-tenant using the apartment gem. Most tutorials I've found all show how to start from scratch. But I find no pointers on how to convert an existing project to have multi-tenancy built in. From my research I found that all models need a tenant ID added in the migration. How do I add this to all existing models easily? Does installing the gem and running the generator suffice? I'm running a rails 5 API application with close to 30 models and using graphql ruby in an Ubuntu 18.04 environment.
Any ideas on how to do this?
Thanks #lacostenycoder for pointing me in the right direction. Here's what I did.
Short answer: Yes, installing the gem, running the generator and creating your tenant model should suffice. Apartment reads your schema and creates schemas for the tenants.
Long answer, my experience:
I Backed up existing data from my database just in-case.
Installed apartment gem
If you are using any PostgreSQL database extensions like I was (pgcrypto, uuid- ssop)you need to understand that the extensions are not automatically loaded into the newly created schema.(look here for more details) do the following:
Follow instructions the github readme to create a shared_extensions schema
Create your first tenant. If it works, all is well. But...
If that doesn’t work, I mean when you create a tenant you get errors like ActiveRecord::StatementInvalid: PG::UndefinedFunction: ERROR: function gen_random_uuid() does not exist
or ActiveRecord::StatementInvalid: PG::UndefinedFunction: ERROR: function uuid_generate_v4() does not exist (more details here, here and here) like it was my case when creating my first tenant, I discovered that once the extensions are enabled on the public schema, they cannot be installed in the shared schema shared_extensions in this case. So you have to change them from the public schema to the shared_extensions schema. get more details here
If you are using uuid-ossp ALTER EXTENSION "uuid-ossp" SET SCHEMA shared_extensions in your rails dbconsole
If you are using pgcrypto ALTER EXTENSION "pgcrypto" SET SCHEMA shared_extensions in your rails dbconsole
The apartment gem will create all models for your tenant once you have it set up correctly and create your first tenant.
For more information on check out some of these github issues on apartment. Here and here.
Took me a day to figure it out and gather that info. I hope it saves you time and headache!
There doesn't appear to be any reason why you can't add this to an existing Rails app. I have not done this myself, nor does there appear to be any specific tutorials on how to migrate an existing app. Follow the gem setup instructions as shown on the README and also see the wiki for additional configurations and instructions. Use TDD wherever possible and expect to make changes to your application to get everything working correctly. Depending on how complex your existing app is will determine how much work this move will be.
You'll likely want to use lvh.me:3000 instead of localhost:3000 as root domain and port in your browser and perhaps use rails s -b lvh.me when starting your local server.
If you want to safely hack through this branch I recommend that you make a full backup of your local development database before you get started so that you can rollback to your stable current version in the event things go horribly wrong. If you're using Postgres for example there's pg_dump and pg_restore
This approach combined with good TDD should get you where you need to be.
Related
I am new with Ruby on Rails and have some issues with it. I am writing my application on Rails and i have to install some pre-defined data in my Database to use it in my application. This data is read-only and never change (for example users and roles. There are no use cases to create new users and roles).
So i have to install this data when my application runs first time. I tried to use Migrations to solve this problem, but my manager told me that it is not a right way, cause migrations are usually used to define DB structure changes and not to install any data in DB.
Can you please help me and tell better way to install my pre-defined data using Ruby on Rails?
You'll be able to achieve this using the seeds functionality:
To add initial data after a database is created, Rails has a built-in 'seeds' feature that makes the process quick and easy. This is especially useful when reloading the database frequently in development and test environments. It's easy to get started with this feature: just fill up db/seeds.rb with some Ruby code, and run rake db:seed:
#db/seeds.rb
User.create name: "test", description: "info"
$ rake db:seed
--
If you wanted static data, you'll be able to use a gem such as the config gem -- which gives you the ability to allocate values in config/settings.yml:
This data is then accessible as Settings.company...
You should use seeds. See this rails cast
You could also look at Dibber, that allows you to define your seeds via YML files.
What you are looking to do is seed the database. Rails comes with a db/seeds.rb that you can use to do this. There are also gems such as seed-fu that you could use.
Here is a short tutorial on seeding a database in Rails.
Hi have an existing rails 4 app which is using a MySQL database.
I now need to add code that creates dynamically a new table for every object and its attributes.
I decided to use a No SQL solution for this. Initially I wanted to use Mongo DB since I was familair with this. However, my company supports only Cassandra/redis/solr. So I have to pick one of these.
I chose Cassandra but Im not finding any tutorials or examples on how to use it with an existing rails app with a MySQL DB.
I found this ORM for rails-Cassandra but no idea how to make it work with an existing Active record - mysql system.
Any ideas would be very appreciated.
Apologize this post has no code. But I couldnt find any answers for this issue on SO so please excuse if any mistakes.
thanks
ActiveRecord and Cequel will be independent.
As shown in their docs you extend a model's functionality by including the Cequel::Record module.
include Cequel::Record
In order to use it in rails you (obviously) need to add the proper gem in your Gemfile
gem 'cequel'
and create the configuration for the project
bundle exec rake cequel:keyspace:create
After that, you will have a config/cequel.yml from where you will define your settings (as you did in config/database.yml for your MySQL)
MySQL models will still use the ActiveRecord
class Foo < ActiveRecord::Base
...
end
while Cassandra ones will use the Cequel
class Bar
include Cequel::Record
...
end
I am learning RoR using M Hartls Rails tutorial book. I am very much new to the world of databases. I created the application(simple one, just on 3rd chapter) and did my RSpec and made few static pages. I wanted to migrate from sqllite3 to postgres.
I changed the database.yml to postgres deleting the full sqlite3 specifications. Now I run my app it does not work? It says 'PG:' Error.
I need to first understand how the data is stored in sqlite? I searched the db directory and I could not find the development.rb or any database file (probably because I altered the database.yml file)
In this case, I did not enter any data as such,(it still does not work , gives me error) but generally, where does the data get stored? and since I changed the database.yml file to postgres, what will happen to the existing data?
what does rake db:migrate command do?
It would be great if someone gives a simple analogy or explanation is to how this is stored then finding a solution for this problem becomes much easier.
sqlite stores its data in files in a folder on your filesystem, using its own system of storage.
postgres will do a similar thing, but in a different folder, using a different system.
You will generally never touch these folders. You don't need to know where they are or how the dbms (database management system, eg sqlite or postgres) stores the data. All your interaction with your dbms will be done either via the terminal, or the dmbs's shell client (which you launch in the terminal aka the shell), or via a desktop client, or via your rails app's own connection with the dbms.
When you make a new rails project you need to create the database it will use. If you switch to using a different dbms then you will need to create a new database in that dbms for your app to use. Google how to do this.
If you have data in one dbms and you want to bring it into a different dbms then you will need to export it from the first dbms and import it into the second dbms. Google how to do this.
rake db:migrate will run any migrations which haven't been run in your current database (ie the one in your database.yml). Rails creates a table in your database to store which migrations have been run already: this is how it keeps track. It will fail if you haven't created the database yet.
So basically I am making a new sample application that will run using an external Postgres database and a model, both created by another programmer who has given me this project.
I am supposed to create a rails app that will implement the model and database in order to add some mapping functionality. The problem is that I truly do not know how to migrate an existing database using the "db_name.sqldump" file they provided me. I have installed psql, created a new rails app and added the "pg" gem, but I haven't been able to create a table with all the model information.
I am not sure if I am being clear but I truly am pretty much lost here with RoR. Any input would help.
Assuming you've a pg_dump file, import it from the command line using either of psql or pg_restore.
http://www.postgresql.org/docs/current/interactive/app-pgrestore.html
Follow this railscast by Ryan Bates - http://railscasts.com/episodes/342-migrating-to-postgresql
To convert your sqldump to a sqlite db, Follow these guides : -
script to convert mysql dump sql file into format that can be imported into sqlite3 db
http://code-n-fold.com/2011/11/28/convert-mysql-dump-to-sqlite-format/
So I am starting to learn rails, with a php and front end background. I created a new rails project and that was going well enough, until I downloaded another rails app off github and installed all dependencies and gems...anyway these problems have been my undoing for the last two days...I would really appreciate some clarification.
How exactly do you manage local databases for a development version as opposed to those external databases for a live version?
Will Rails build a local database automatically after an application is imported from Github for instance? Or does one have to be created manually, also should it have the same authentication credentials that the downloaded uses to talk to its database?
Also, after I downloaded PostgreSQL and its gem, I can no longer start rails server for my old rails project, or for my new one for that matter, both get these errors:
gems/actionpack-3.0.16/lib/action_dispatch/http/mime_type.rb:98: warning: already initialized constant PDF
gems/activerecord-3.0.16/lib/active_record/connection_adapters/postgresql_adapter.rb:950:in `initialize': FATAL: role "postgres" does not exist (PGError)
Since you're using postgresql (which possibly shared by several applications), and in my understanding, two rails applications usually do not share namespaces other than database, I guess you've not modified config/database.yml file.
By convention, the default development database name is development, so, if you haven't touch the configuration file, the two applications share same database options, cause conflicts.
I usually modify the database name to development_SomeApplicationName (replace SomeApplicationName with some meaning application name to differentiate database name) just after creating new application.