I have 3 different organizations types and 3 different databases structures: one for each type. When org1 registers I'm creating a new database instance for org1, and when org2 registers I'm creating a new db instance, and same for org3.
Now, how do I run migrations for three different db:structure from my application soon after I create a new database instance for organizations.
I am creating a db instance from application by:
ActiveRecord::Base.connection.execute(sql)
How can I do this? Is there another approach I should be using?
The command you are looking for is establish_connection. You might
want to look at the rails rdoc. Search for "Connection to multiple
databases in different models" in
http://api.rubyonrails.com/classes/ActiveRecord/Base.html.
Connections are usually created through ActiveRecord::Base.establish_connection and retrieved by ActiveRecord::Base.connection. All classes inheriting from ActiveRecord::Base will use this connection. But you can also set a class-specific connection. For example, if Course is an ActiveRecord::Base, but resides in a different database, you can just say Course.establish_connection and Course and all of its subclasses will use this connection instead.
Related
I need to create a new rails application that will use an existing external Microsoft SQL server database as its primary database. This DB is running on an external server that i'll need to connect to. Here where i work there's a separate DB Admins section so im not sure what steps i need to perform. I think the easy part is connect to the server and set the app to work with that DB. But i get confused after that.
Should i create a db dump and migration?
Should i add models to represent existing database structure?
In case i need to create new models and tables in the db...
Should i generate its models from the rails generator and run migrations on the db or contact the DB admins to create the tables, and then specify manually the models inside the app? <- this really confuses me
Thank you in advance and sorry for my english! :)
EDIT!! -> The Rails Way
I've found another great way to integrate multiple database data... You can define a model and specify in which database it's located (so db connection is never closed)... This is definitely The Rails Way and should be followed...
Here's a nice tut:
Multiple Databases in Rails
TL;DR
Define your secondary_db in database.yml
Define your model and specify its database and table name
Class ExternalDatabaseModel < ActiveRecord::Base
establish_connection(:secondary_db)
self.table_name = "the_table"
self.primary_key = 'someWeirdIDColumn'
end
Then use as any other rails model, specify relationships and more :)
Hope it helps to somebody!
I would suggest you take a look at tiny tds gem: https://github.com/rails-sqlserver/tiny_tds. It's really use to config and use... you can use it to connect on your external sql server db and make the queries you want. Don't know which type of system you're working, but if you're constantly retrieving data, making external requests may get your system slower. Depending on your application, you could consider synchronizing the data, making a local database redundant. Hope it helps you, good luck!
EDIT: about the models part: if you're going to retrieve the data from that sql server every time you need, than you don't need to store it locally. But if you're doing that redundancy, you should create the models with the attributes you'll need, than when you retrieve from the server, you save it normally, just attributing the values to your model and calling save! method.
When customers is created in my app ruby on rails,I want to create database for each customers without break/closing my exiting/running application database.When particular customer is login then I want to CRUD operations on both databases.
My app Database name is myapp.
E.g when customer 1 is created in myapp I want create One database for customer_1.
when customer 2 is created in myapp I want create One database for customer_2.
When customer 1 is login in myapp , when he does any crud operations then I want save all data in Myapp database as well as customer_1 database.
try sequel
Sequel is a simple, flexible, and powerful SQL database access toolkit
for Ruby.
Sequel provides thread safety, connection pooling and a concise DSL
for constructing SQL queries and table schemas.
i think this tool can help you create many database set on you app
You can try to use establish_connection (using before_filter in application_controller) http://www.runtime-era.com/2012/11/dynamic-activerecord-database.html
first make another label and put there all setting of databasee in database.yml then in respected model from where you want to connect different database create two different methods and assign their database connection by establish_connection(database.yml files label name here such as "development") and another method put another db name, which location you want to switch database then call these methods.
I am implementing a Rails application that needs to aggregate search results from N independent heterogeneous databases. An example use case would be:
User queries "xpto"
The query is submitted to all the databases registered on the system
The results are transformed and combined in a predefined format
User gets the results
The application needs to provide an extensibility point for the introduction of new databases in the system. A database here can be of different kinds - a flat file, SQL database, REST interface to an SQL database, etc.
If I was working in C#/Java, ignoring speed issues, I would define a plug-in management system where each host would have a plug-in that would know how to query and transform the results of the host. New hosts would be easily introduced by defining a new plug-in and configuring the host in the system.
I am new comer to rails and I am looking for either ideas, tools or design patterns that can help me to solve this problem.
My best guess wolud be to write a custom ActiveRecord Adapter that would query all your databases and combine the results.
From the API reference:
Connections are usually created through ActiveRecord::Base.establish_connection and retrieved by ActiveRecord::Base.connection. All classes inheriting from ActiveRecord::Base will use this connection. But you can also set a class-specific connection. For example, if Course is an ActiveRecord::Base, but resides in a different database, you can just say Course.establish_connection and Course and all of its subclasses will use this connection instead.
I am about to create an application with Ruby on Rails and I would like to use multiple databases, basically is an accounting app that will have multiple companies for each user. I would like to create a database for each company
I found this post http://programmerassist.com/article/302
But I would like to read more thoughts about this issue.
I have to decide between MySQL and PosgreSQL, which database might fit better my problem.
There are several options for handling a multi-tenant app.
Firstly, you can add a scope to your tables (as suggested by Chad Birch - using a company_id). For most use-cases this is fine. If you are handling data that is secure/private (such as accounting information) you need to be very careful about your testing to ensure data remains private.
You can run your system using multiple databases. You can have a single app that uses a database for each client, or you can have actually have a seperate app for each client. Running a database for each client cuts a little against the grain in rails, but it is doable. Depending on the number of clients you have, and the load expectations, I would actually suggest having a look at running individual apps. With some work on your deployment setup (capistrano, chef, puppet, etc) you can make this a very streamlined process. Each client runs in a completely unique environment, and if a particular client has high loads you can spin them out to their own server.
If using PostgreSQL, you can do something similar using schemas.
PostgresQL schemas provide a very handy way of islolating your data from different clients. A database contains one or more named schemas, which in turn contain tables. You need to add some smarts to your migrations and deployments, but it works really well.
Inside your Rails application, you attach filters to the request that switch the current user's schema on or off.
Something like:
before_filter :set_app
def set_app
current_app = App.find_by_subdomain(...)
schema = current_app.schema
set_schema_path(schema)
end
def set_schema_path(schema)
connection = ActiveRecord::Base.connection
connection.execute("SET search_path TO #{schema}, #{connection.schema_search_path}")
end
def reset_schema_path
connection = ActiveRecord::Base.connection
connection.execute("SET search_path TO #{connection.schema_search_path}")
end
The problem with answers about multiple databases is when they come from people who don't have a need or experience with multiple databases. The second problem is that some databases just don't allow for switching between multiple databases, including allowing users to do their own backup and recovery and including scaling to point some users to a different data server. Here is a link to a useful video
http://aac2009.confreaks.com/06-feb-2009-14-30-writing-multi-tenant-applications-in-rails-guy-naor.html
This link will help with Ruby on Rails with Postgresql.
I currently have a multi-tenant, multi-database, multi-user (many logons to the same tenant with different levels of access), and being an online SaaS application. There are actually two applications one is in the accounting category and the other is banking. Both Apps are built on the same structure and methods. A client-user (tenant) can switch databases under that user's logon. An agent-user such as a tax accountant can switch between databases for his clients only. A super-user can switch to any database. There is one data dictionary i.e. only one place where tables and columns are defined. There is global data and local data. Global data such as a master chart-of-accounts which is available to everyone (read only). Local data is the user's database. A new user can get a clone of a master database. There are multiple clones to choose from. A super-user can maintain the clone databases.
The problem is that it is in COBOL and uses ISAM files and uses the CGI method. The problem with this is a) there is a perception that COBOL is outdated, b) getting trained people, c) price and d) online help. Otherwise it works and I'm happy with it.
So I'm researching what to replace it with and what a minefield that is.
It has past time and the decission for this has been to use PostgreSQL schemas, making multitenant applications, I have a schema called common where related data is stored.
# app/models/organisation.rb
class Organisation < ActiveRecord::Base
self.table_name = 'common.organisations'
# set relationships as usual
end
# app/models/user.rb
class User < ActiveRecord::Base
self.table_name = 'common.users'
# set relationships as usual
end
Then for migrations I have done that with this excellent tutorial. http://timnew.github.com/blog/2012/07/17/use-postgres-multiple-schema-database-in-rails/ use this, this is way better than what I saw in other places even the way Ryan Bates did on railscasts.
When a new organisation is created then a new schema is created with the name of the subdomain the organisation. I have read in the past that it's not a good idea to use different schemas but it depends on the job you are doing, this app has almost no soccial component so it's a good fit.
No, you shouldn't use multiple databases.
I'm not really sure what advice to give you though, it seems like you have some very basic misunderstandings about database design, you may want to educate yourself on the basics of databases first, before going further.
You most likely just want to add a "company id" type column to your tables to identify which company a particular record belongs to.
I have a 'legacy' DB2 database that has many other applications and users. Trying to experiment with a rails app. Got everything working great with the ibm_db driver.
Problem is that I have some tables like schema1.products, schema1.sales and other tables like schema2.employees and schema2.payroll.
In the ibm_db adapter connection, I specify a schema, like schema1 or schema2, and I can work within that one schema, but I need to be able to easily (and transparently) reference both schemas basically interchangeably. I don't want to break the other apps, and the SQL I would normally write against DB2 doesn't have any of these restrictions (schemas can be mixed in SQL against DB2 without any trouble at all).
I would like to just specify table names as "schema1.products" for example and be done with it, but that doesn't seem to jive with the "rails way" of going about it.
Suggestions?
Schemas in DB2 are a very handy way to provide separate namespace to different applications. For example, you can separate all database objects for an application called "recruiting" from say application called "payroll". You can have objects (tables, views, procedures etc.) with the same name reside in multiple schemas and not colide with one another. Having your application set a schema is a handy way for it to say "hey, I am a payroll and I only want to work with my objects". So, what happens when you want to work with objects owned by another application? Well, in traditional procedural programming languages your application code would explicitly specify the schema when referencing an object in another schema or you would just do a SET CURRENT SCHEMA to switch to another schema. The problem with ORMs like ActiveRecord in Ruby on Rails is that you are not supposed to use SQL i.e. you don't have a good "Rails way" to specify schema when referencing an object. You can use find_by_sql and qualify your objects in the SQL statement but this is not what RoR people will consider to be good Rails.
You can fix things on the DB2 side. You can define a view per table in the "foreign" schema but you will have to take care to name the view so that it does not colide with what you already have in your primary schema. And, when you do that, you will undoubtedly create names that are not true Rails names.
Rails people are very proud of the "Rails way". It makes it very easy to create new applications. Rails is really awesome in this space. However, when it comes to integration with what is already out there Rails ... how do we say it ... sucks. I suggest you will have to accept to do things that are not the best examples of the Rails Way if you want to work with existing database structures.
How do i work with two different databases in rails with active records?