Accessing ActiveRecord models from MongoDB application - mysql

I have an old app built in Rails 3 using MongoDB for the database (Mongoid as the adapter).
I am moving it to Rails 4 and using MySQL. My plan is to map the collections into their own tables through a script and copy the data. I'm comfortable doing that part. What I cannot for the life of me figure out is how to connect to the MySQL DB.
I have created the new app in Rails 4 and the new DB and, as an example, a table for Contacts which maps to the collection in the MongoDB. What I want to do is find all contacts in Mongo, then connect to the MySQL DB and insert the records into the table.
How do I do that last part?
Thanks
Robin

I managed to do this as follows.
1) Created the db schema in the new application. At this stage I didn't worry about associations as I would be setting association ids manually.
2) In a file I called transition.rb in the old app, I defined migration classes for each of the classes I wanted to transfer e.g. for the class Product, I defined a transition class called NewProduct using the following pattern:
class NewProduct < ActiveRecord::Base
file = File.open("#{Rails.root}" + "/config/database.yml")
dbconfig = YAML::load(file)
establish_connection(dbconfig["development"])
self.table_name = "products"
end
By adding the mysql2 gem to the old MongoDB application, I was able to use this pattern to connect to the relevant tables in the new application.
3) For each of the classes, I then iterated over the existing records, mapping them to the new tables through the migration classes. There are some challenges where MySQL doesn't have the columns available to map directly e.g. no Array column type in MySQL. For these situations, I created a separate class and manually created associations.
There were certainly some parts of trial and error but on the whole it has worked quite well. The only part I couldn't complete programatically was associating uploaded images and documents back to the relevant products however due to the file naming structure for those uploads, it won't be a huge amount of manual effort to create the associations.
For those who are interested this is the gist of the file I used.

Related

How can I query the existing records in my imported database in Rails?

I am now developoing a rails project, but I am using an existing database of MySQL. Well, I have already connected the project with MySQL database, and in former times, I used to created models together with the database migration.
Like, when I create a new Class for the Model part, I used "bundle exec rake db:migration" to create a new database table, and the activerecords are connected.
But now the sequence is a little bit different, I had my database tables first, and then I wanted to query the records using a newly-built class on rails. For example, I had a table of students in MySQL database, and then I wanted to query the records of all the student by creating the new class Student, and create a new search method in the Student Controller.
But now I have not even a clue, because this is new to me, anyone can come for a little help??? Thanks a lot!
All you have to do is setting table name.
class MyFancyModel < ActiveRecord::Base
self.table_name = "myFancy_table_name_1234-5"
end

Connecting a new Rails app to an existing MySQL database

I have a brand new Rails app that I want to hook into an existing MySQL database to do some reading and writing. I've already edited my database.yml file to connect to the new db. rails c and rails s don't throw errors which lead me to believe that the connection is valid.
I haven't created any models or migrations yet. I was wondering if there was an easy way to get the models I need into my Rails project.
I'm able to connect to the db with Sequel Pro if I need to export a backup or a schema. Or do I need to generate models and copy all of the column types and everything manually?
Thanks for your help.
ActiveRecord will detect the column names for you! You don't need to create any migrations, but you do have to make the models.
When you make an active record model, active record will deduce the table name that you're connecting to by pluralizing the class name.
So:
# app/models/book.rb
class Book < ActiveRecord::Base
end
Will try to find a table called "books". You can then instantiate an instance of Book, and you'll find it has getters/setters for your field names.
If your tables don't follow this naming convention, you can also define your table names manually:
class Mouse < ActiveRecord::Base
self.table_name = "mice"
end
http://api.rubyonrails.org/classes/ActiveRecord/ModelSchema/ClassMethods.html
Start by creating empty model files with the following structure, for an orders table:
class Order < ActiveRecord::Base
end
With just that much in place, you can get all the active record magic on the orders table. You could do the following from the console:
> Order.count
=> # Shows the number of rows in orders table
> Order.first
=> # Return the first row from the table
> Order.where(...)
=> # Return selected rows from the table meeting the specified criteria.
See Active Record Query Interface for more active record features that you get by subclassing from ActiveRecord::Base.

Rails building predesigned database

I'm a beginner in Rails and I have a complete database designed with a database design tool. (For a startup so quite confidential)
Can I write all the tables and their columns straigth into the migration file and then migrate or should I run the >> rails generate model ... for every table in my database?
And what about the join tables? Do I need to create them to or do they get created when I write the table classes for association?
I have some experience in MySQL from school so things are a litle strange switching to Rails.
Thanks!
I think you need to read more about migrations, specially for join-table, association-tables.
For your question to create all databases, and all tables in one migration file, I think that is valid, but that is bad, you can write code as the following:
class CreateTables < ActiveRecord::Migration
def change
create :table_1 do |t1|
t1.string :name
end
create :table_2 do |t2|
t2.string :name
end
# this for join table
create_join_table :table_1, :table_2
# this for associations
add_reference :table_1, :table_2, index: true
end
end
But this tables will create in your database that is called database.yml file, and you can see your tables using mysql, but if you want to use active-record functions as(new, create, update, save, validations, ...), so you'll need to create model for these tables
rails generate model is just a template generator to create
a migration file under db/migrate
a model file under app/models with some template
some related test files
All of these can be done manually.
In your case, you can create your migration file (for building the tables) and model file separately, no need to stick with generate function.
(1)Can I write all the tables and their columns straight into the migration file and then migrate?
Yes, you can, but I would not recommend it. Because at first you need to create migration files in the db/migrate directory and definition migration class by yourself, I think it is very boring. If Rails can help you do this , you doesn't need to do it yourself, but you should understand how migration works. Secondly, create you needed tables at present unless just a test or small rails application, because customer(maybe yourself) needs and expectations are changing. Perhaps the end you doesn't use some tables at all or change tables frequently.
(2)should I run the >> rails generate model ... for every table in my database?
You are a beginner in Rails, so am I. I suggest you use the rails generate command to create tables, models, controllers..., this is the foundation of Rails learning, and it is very convenience.
(3)And what about the join tables? Do I need to create them to or do they get created when I write the table classes for association?
You can create it by yourself, can also use rails generate command.
Rails guide can provide you with direction and help.

Connect Ruby on Rails to read data from Non Rails Database

I'm developing Ruby on rails applications and my source data is mysql table that developed by other developer using PHP+Mysql 2 years ago,
my rails application just need to read and query 5 tables inside old database system (no non modify), is this possibly?
if yes, how can rails can read the model if the table not using standard name convention
( I did some research previously and read about connection_ninja / octopus - easy database sharding, but I would like to give specific question incase one of you have some inputs / experience and want to share it), many thanks
If you create a model to match each table, you can use the following in the model:
class Product < ActiveRecord::Base
self.table_name = "PRODUCT" # table name for the model to use
self.primary_key = "product_id" # primary key of the table
end
Click here for more information about overriding naming conventions for legacy databases.

web2py dal howto define model at runtime

I am a newbie to wewb2py,is it possible to create at runtime a model of a legacy database, for using DAL with it? I saw that there are some scripts that create the model file, but I do not know whether it is correct to put this file in the model directory of my application, I think not, I did some experiments, I can connect to the database with DAL querying its tables and for every table I can get the definition of the fields, the I tried to define the table with define_table,it works but try to create the table on the database and return an error because the table already exists; this is the relevant part of my code:
conn_string = "mysql://{0}:{1}#{2}/{3}".format(user,pwd,host,db_name)
db = DAL(conn_string)
db.define_table('test1',Field('prova','string'))
it works only the first time, when the table test1 does not exist yet on the database, I do not need to create the tables only work with their data, can you put me on the right way?
db = DAL(conn_string, migrate_enabled=False)
The above will prevent web2py from doing any migrations, including attempting to create any tables.