Ruby and Rails: Adding a column to a model without migrate - ruby-on-rails

There are a number of questions here about adding columns to a model via rails migration files and a rake db:migrate.
In this case, however, the application is basically a CRUD on top of an existing SQL Server database that is generated by another application. That is, I don't control it. Those who do control the database have added several columns to a table.
What I need is for the Rails app to respect the changes made to the database without assuming it has full control over the table structures.
I've tried plugging the new fields into the model and controller files, but sql queries give TinyTDS errors saying the new fields don't exist. Queries by hand (via SQL Server Management Studio) work fine. What am I missing? Why doesn't Rails recognize the new fields when they appear in the table model?
UPDATE:
It turns out that the problem is more subtle than I though when asking the initial question. As background, this application is set up with two databases, one production, one development/test. They are both on the same SQL Server database server. What's actually happening with the missing columns is that the Rails app pulls from production no matter what environment I use. Even when I change both environments to use the same development database (in database.yml), the app continues to query the production database.
Perhaps this is a problem between Rails and SQL Server. I've cleared all caches and cleared all database connections, but it makes no difference. It seems that the Rails app is caching the database name and login info somewhere.
One day I'd like to get this fixed, but for now I'll simply move the development database to another server for testing.

ActiveRecord has a cache of the table fields. If you want to reset the cache for a model without restarting your application, you can do:
MyModel.reset_column_information

Related

How can I remake databases without losing data on Ruby on Rails?

Sorry that this question is not a proper one on this site, but I really thought that I needed to know how to do that, because in production environment, if I delete all data all the time when I delete a model, this should be a serious problem.
In detail
In case re-making the same named model,I mean after delete a model, then make the same named model.
It should be like
rails destroy model Name
and after that
rails g model Name
And usually errors occur in this case, we can basically fix the errors by using the command rails db:schema:load, but this command destroys whole data of an existing database, but I don't want to lose the data so I wonder if there are any other good ways for this.
Thanks
Normally, this should not affect your production database, since Ruby on Rails knows what migrations have run already and that's why you should use rails db:migrate to update your database.
If your production database has old entries that you want to reuse, you can also change the Active Record Migrations so that the affected table does not get dropped and recreated but altered instead.

How to manage migrations when multiple apps share the same database in Ruby?

I have a Rails app and a Sinatra app, sharing the same database. The Sinatra app uses ActiveRecord.
Can I run migrations from within each app, as if they were in the same app? Will this cause any problems?
The schema.rb file in the Rails app tracks the current migration via
ActiveRecord::Schema.define(:version => 20121108154656) do
but, how does the Sinatra app know the current version the database?
Rails 3.2.2, Ruby 1.9.3.
The version column in the schema_migrations table equate to the time stamp on the front of the ruby migration file example: 20130322151805_create_customers.rb So if two ore more applications are contributing to the schema_migrations table roll backs will not be possible if rails can't find the down() method (because it will not find a migration file contained in another app ie db/migrate/...)
I have a current situation that is exactly this and I have opted to have a master ActiveRecord app that manages migration and data conversions as our database evolves. Keep in mind that part of the deal is to keep models up to date as well. This has been time consuming so we are considering breaking apart the DB in to business domains and providing APIs (JSON) to query support data for another application. This way each application manages it domain and is responsible for exposing data via API.
regards.
If you connect both applications to the same database you should be able to run migrations on it but I strongly suggest you use another option since you will almost surely hit a wall at one time or another:
split the database in two if possible with each application responsible for its own database /migrations.
have one application considered the "master" database and use another database for the data specific to the second application but make it connects to both database (each application still only apply migrations to one database)
If you need to share data between multiple applications another option is to implement a REST service in one and use it on the other, you can have a look at the grape gem for a simple way of doing so.
Edit: I realize I forgot to speak about the activerecord migration, there is no longer any "version" of the schema, what activerecord does is that it read all your migration filename, extract their identifier (the starting part) and check if they have already been applied so in theory you can run migrations from two applications on the same database provided they don't interfere.
But if both migrations act on the same tables you will almost certainly run into big troubles at one point.
I disagree with Schmurfy, even if his presented options are valid, its a bit of an overkill to share data through REST (granted, its pretty easy to implement with ruby / rails).
If your case is simple you could just use one database from both apps, and since you use AR in both of them you have no problems with versioning, AR takes care of that.
Also i dont know what happens if you run db:migrate from both apps simultaniously if you use a inferior dbms like mysql which does not allow DDL in a transaction, certainly nothing good..
Also it would bother me to look which app needs what column and not have the migrations in one place. You could use a shared repository to manage the migrations from both apps.
Rails migrations store current database version in schema_migrations table in the database. So both of your apps will be able to check the current version.
The version numbers are timestamps, so there shouldn't be any problem with duplicate values, as it'll be almost impossible to generate two migrations at the exact same millisecond. So you should be fine here.
The only problem I see is that when you rollback a migration in one app, it'll set the db to the previous known version and I'm not sure if it will pick the previous one from the db (which could be from the other app), or the number from the previous migration file. You may want to test that scenario to make sure.
I decided to put all migrations in the Rails app because:
Since there is only one database
Rails manages migrations
This has worked well.
This simplifies the system because all migrations are stored in one place. And, the Sinatra app doesn't need to know about them anyway.

Best Practice for DB Schema in Ruby on Rails

I'm a PHP programmer for over a decade and making the move to RoR. Here is what I'm used to from the PHP world:
Create DB schema in a tool like MySQL WorkBench -- and make fields precisely the size I want without wasting space (e.g. varchar(15) if it's ip_address).
Write models using Datamapper and place those exact field lengths and specifications in there so my app doesn't try to put in any larger values.
In the RoR world from what I've seen over the past two days, this seems to be the flow suggested:
Add fields / schema using the command line which creates a migration script and apparently created large ass fields (e.g. "ip_address string" is probably making the field varchar(255) in the db when I run the migration).
Put in validations during model creation.
Am I missing something here? What's the process in the RoR world for enterprise level applications where you actually want to create a highly customized schema? Do I manually write out migration scripts?
The scaffolding is what you use to get started quickly. But before running the migration, you can edit it and add constraints and specific column lengths.
Validations specified in the model (in the ruby code) does not carry the same level of security as validations /constraints specified on the database. So you still need to define those on the database.
While it is possible to work with Rails without migrations, I would strongly advice against it. In some cases it cannot be avoided (when working with legacy databases for instance).
The biggest advantage of using the migrations is that your database schema, accross different platforms, can be held in sync through different stages. E.g. your development and your production database. When deploying your code, the migrations will take care that the database is migrated correctly.
You can edit the migration scripts before you run the migration in order to customize the fields.
Yes, if you need to tweak the defaults, you edit the migration scripts.
Also note that you don't need to use migrations, they're a "convenience" while iterating through DB development. There's nothing that says you must use them. The active record pattern doesn't rely on how the DB tables/fields/etc. are created or defined.
For example, migrations are useless when dealing with legacy DBs, but you can still write a Rails app around them.

Migrating database (SQLite) from one rails application to another

I currently have a system in which one rails 2.3.2 has a database with all of my content data on. I have since created another application which is using rails 3.1 and is very similar but with some more features (hence changed database structure (added and removed columns around the place)).
My issue is that I'm not sure how to get the data (I only really want three values from all of the "entries" (I don't work with databases often and so don't really know the lingo)) in one of my models from one database (SQLite production) to the other (also SQLite production).
I looked into db:seed however it turns out that rails 2.3.2 doesn't support db:seed and so I cannot use this.
Any ideas on how I can do this and easily add the missing information to these entries aswell (such as the published_at column which is new in the newer application which needs to be added for each entry)?
Best Regards,
Joe
If you need to migrate the whole application, check this out: Migrating from Rails 2 to Rails 3
If you only need to manage the sqlite databases, there are a lot of tools to do that. Here's the complete list

Ruby on Rails: is it okay to use old school database access without migrations?

I'm switching to RoR from ASP.NET MVC. Yeah, migrations are cool, but I do not need to use different databases in my web applications. Postgresql will do just fine.
So is it okay if I use PGAdmin to create and administer my databases and schema and avoid all these fancy migrate, rake etc?
Update
Thanks everyone! Now I better understand what migrations are, and why I should use them.
I don't think that's what migration means.
Migrations in rails (and in other frameworks) is a method by which you can use to update your database schema when there are multiple versions of the same database running
For example, you may have two databases, one running on your production server, and another running locally for development. After a few days of coding, your local development database may looks a bit different. With migrations, you can simply push your code to the production server and then run the migrations to automatically update your production database so it is up-to-date with the one you use locally for development.
So, to answer your question, Yes it is OK but you might not get a few of the migrations niceties when the time comes that you'll have to maintain multiple versions of your database.
Have to agree with charkit but one (rather two) important note why you should use migrations: Migrations don't make up the model definitions. They are stored seperately in a file schema.rb. This defines the rows and tables of your database. When looking into the file, you find these lines:
This file is auto-generated from the current state of the database. Instead of editing this file, please use the migrations feature of Active Record to incrementally modify your database, and then regenerate this schema definition.
The second reason is for testing: you can easily set up a test database to run all your tests against without the need to touch the "real" database. I know when developing, this is not a big problem but this will get more important after some time.
So, yes, it is possible to use PGAdmin to create all your database related stuff but you should not forget to always keep the schema file up to date and come up with a solution for testing.
With migrations you're able to develop your database schema in Ruby and this is usually database indpendent.
In short, spend the 20 minutes or so to really get migrations and the value they add. Then determine whether or not you want to ditch them. Strangely for me I learned Rails before I started my first MVC project; one of the things I missed most was migrations.
From a technical standpoint you should be fine without them.

Resources