How to run a rails migration as sql file - ruby-on-rails

My database admins do not want to control access to any drop/alter/create commands. Is there anyway to emulate what rails is doing to the schema migrations table and convert the migrations themselves in a reliable way to fake rails out into thinking it has been ran and also handle rollbacks? They want to run this from their end of course. I have seen a few suggestions, but no wholistic approach. Perhaps the answer is it really shouldn't be done, which is what I think right now as I believe it will just cause headaches and unreliability down the road.

Related

Can you just change Rails Schema without Migrations?

I'm using bcrypt for Rails API authentication - This is ofc after many hours of trying to figure out how to get Devise to work via Rails api to no avail. (trying to do API only with React frontend).
Anyways, I made it until technical debt had to be paid. BCrypt password_digest and Devise Hashed_password are at a stalemate and I can't seem to get one to ignore the other. I need to change that portion of the schema to accommodate for bcrypt. What's the best way to go about this?
Doing database transformations without using migrations is as easy as running rails db which will start the CLI for your database and typing the SQL. But then you have to repeat those steps across the test/development/production databases and make sure any other developers working on the project also perform those steps on their local databases.
This is a really error prone process and actually solving the problem with migrations is probably a lot less insurmountable than you think.
What's the best way to go about this?
The best solution to ignorance is knowledge.
ActiveRecord migrations are just a Domain Specific Language (DSL) to create SQL queries and a mechanism to run migrations against different databases and keep tabs on which migrations have been run through a metadata table in the database.
Even if you can't express whatever query you are trying to perform through the DSL you can still use any arbitrary SQL string.

Why using migration in RoR or Sinatra?

Perhaps a stupid question, and without code, so I'm not sure I'm on the right StackExchange site. If so, sorry and give me a comment please.
I begin programming in Sinatra (only intranet until now) and in the samples they almost always use migration with activerecord, the same with RoR.
I have experience enough with activerecord itself and it is very helpfull but I'm not sure why migration is always used ? If I create a project I just create a SQL script or a Ruby activerecord script that does the creation of the DB for me and that's it..
If I need the site or script somewhere else I just need to execute that script and ready.
Obviously I'm missing here a lot, so who can me explain the other benefits or point me to a good explanation ?
From Rails docs:
Migrations are a convenient way to alter your database schema over
time in a consistent and easy way. They use a Ruby DSL so that you
don't have to write SQL by hand, allowing your schema and changes to
be database independent.
So, the main two benefits are:
It's like Git for db schema, you won't know how that's useful until you are in a mid-size or big project with many contributors and someone makes a bobo :)
You write ruby code to build your db schema, this way if you decide to move from mysql to pg for example, you don't need to open up pg manual and check code compatibility
Update
In the api docs of migrations, you will find many nice use cases (to be honest i didn't know about half of them) ... check it out (http://api.rubyonrails.org/classes/ActiveRecord/Migration.html)
Building a creation script for your database is great, provided two things:
All your database deployments are on new machines
You get your database schema exactly right the first time
In our modern agile environment we not only don't believe it is possible for a project larger than a few lines of code, we also don't encourage aspiring to it.
Active Record's Migrations offer a way to describe your database incrementally. Each "migration" defines how to add its features to the database ("upgrade"), and how to remove them if necessary ("downgrade").
When running migrations, on top of actually running the scripts, Active Record also maintains its own table (schema_migrations), to remember which migrations have been applied to the database, and which are pending.
This enables you to build your database alongside the features as you develop them. It also facilitates working in teams, since each team member develops her own migrations, and Active Record "stitches" everything together, so you don't have to maintain a monolithic creation script.

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.

Usefulness of db migrations rollback

Many people talking about db migrations, especially about its rollback possibility.
I doubt, whether it is useful at all, because schema of db and model are tightly connected with application logic (MVC).
Suppose i've done rollback of some migration. And what ? The application will not work, because its logic fully relies on db.
What are the use cases of rollback ability for db migrations ?
Update 1
The main question
Why the rollback is presented as a feature, when i need to change the code ?
I don't create the migrations, like "add_another_field_to_table". Instead, each migration file fully describes each table in DB. When i need to change something in my DB, i just change the migration file, but don't roll it back.
Really, if i rollback the migration, it does't brings me back in time, like a version control does. I have a lot of work, when changes are planned and rollback gives me nothing.
The point of rollback is that you rollback code and DB at the same time. The scenario is you upgrade your code and your DB on your production server, then you find a bug and you really need to go back. So rollback your code and use your down migration to roll back your DB.
What are the point of Up migrations?
You create table structures.
You code round it, it works well.
You put site into production, everyone is happy.
Oh, wait, they want a new feature that involves adding a column to an existing table.
How do you handle this? You have to add a column to your development tables, test code, update live site without forgetting to update live DB at the same time (cos if you do there will be big errors) And also remmember to preserve existing live data. This aspect of DB management can be a real pain without a nice managed solution like rails has.
So ...
Code a one line migration that adds a column
Run migration on dev copy, scehma.rb will update
Code new features, if you need to check DB schema use schema.rb NOT migration files.
Now your ready to release on production ....
Update code on production
Run migrations on production. Rails will automatically work out what needs to be applied and do it for you!
Sure, with you adding one column it's not that confusing to do it yourself.
But what if there were 3 programmers all adding migrations? What if you have many live sites, all at different versions? Is that live site 2 or 17 migrations behind? What do I have to do to get the DB up to the latest code, whilst preserving live data? Can you see how this would very quickly get confusing to deal with?
Rails migrations (and practically every migration system works on the same principles) are designed to make updating DB structures really easy. Well worth using properly.
I've found that rollbacks are only useful if they are done locally, ie while you're working on a new bit of code. Once a migration has been committed into your version control system, if you realise there was a mistake then it doesn't really work to roll back the migration because other developers will have pulled the migration down and run it, so you'd need to tell them to roll back as well - this is too difficult to manage and also makes you look incompetent :)
Better in this situation to just do another migration to fix the problem, then everyone (including your production server) just sticks with the pull & migrate system.
Don't really understand your problem, but i try to explain a bit the rollback.
You do rollback if you want to undo the changes by the respective migration. This means that the database will be modified, and also your schema.rb will be automatically regenerated. When you do this probably you want to remove the referencing code too. For example if you removed a field from the model, probably you don't want to refer to that attribute in your code. If you try to access then will gives you undefined attribute exception. That's it.
Can become a bit cumbersome to rollback for example if you created some model 10 migrations before, and you want to change some fields. It's better to create a new migration and modify there, instead of rolling back to the respective migration.
Update 1
Read your update, and i think yo don't use the main advantage of migrations, the flexibility.
But your solution gives more overview of the database situation. If you like to do that way, I suggest the following steps in order.
Roll back to the respective migration.(rake db:migrate VERSION=XXX, I like better rake db:rollback STEP = 2 for example, rolls back 2 migrations, STEP optional)
Make your changes
Migrate your database to update all the tables, and get to current migration version.(rake db:migrate)
This feature don't affect your models or something, just changes the migration file, regenerates your schema.rb and changes the database structure, nothing else. Can't do code rollback like with version control system, and don't really has sense to do something like that. You have to take care about not using removed fields. Rails has automated mapping between database fields and model attibutes, for example if you have an user_id in your comment table, you can call it as an attribute in your model, comment_instance.user_id.
Consider a scenario where you use capistrano to deploy your site and create timestamped snapshots of each deployment. Using the timestamp on the folder and your migrations, you could identify which versions of the code and schema go hand in hand and perform a rollback.
A git repository would give you similar options.
Of course, the real problem is that once users of a site start adding data, that will potentially get purged too, unless you back it up before a rollback and painstakingly restore it at a later date.
I use migration rollback locally with rake db:migrate:redo while working on migration code and before final commit.

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