What's Does the [5.0] in Rails 5's Activerecord::Migration Mean

What’s does the [5.0] in Rails 5’s ActiveRecord::Migration mean?

It is a class method of ActiveRecord::Migration and is defined here.

It allows us to select the version of migrations we wish to use between 4.2 and 5.0. The method throws a:

"Unknown migration version ... "

error if an incompatible version is passed as an argument.

Production ready versions of ActiveRecord don’t have that method so it should go away as soon as Rails 5 goes out of beta.

What’s does the [5.0] in Rails 5’s ActiveRecord::Migration mean?

It is a class method of ActiveRecord::Migration and is defined here.

It allows us to select the version of migrations we wish to use between 4.2 and 5.0. The method throws a:

"Unknown migration version ... "

error if an incompatible version is passed as an argument.

Production ready versions of ActiveRecord don’t have that method so it should go away as soon as Rails 5 goes out of beta.

What are the brackets [5.1] after ActiveRecord Migration and how does it work?

This is the new migration versioning introduced with Rails 5. The number indicates the migration version the migration was created with, in this case version 5.1 and should be used with Rails versions >= 5.0.

This is a class function def self.[](version) of the ActiveRecord::Migration, which calls Compatibility.find(version) and is used for backward compatibility.

Here are the code references from GitHub:

  • ActiveRecord::Migration::[]
  • ActiveRecord::Migration::Compatibility

ActiveRecord::Migration deprecation warning - asks for Rails version, but I'm not using Rails

Because Active Record wants to know in which version the migrations were generated. Sometimes a default in a migration can change between Rails releases (when I say Rails releases I'm talking about the release of Rails the framework, not rails the gem).

So let's say you have a migration like:

create_table :todos do |t|
t.string :content
end

And it was generated with Active Record 4.2 (and thus Rails 4.2 release). In Rails 4.2, strings columns have the default size of 4 bytes.
In Rails 5.0, the Rails team decided to change the default size to 8 bytes. If you upgrade the gem to 5.0 rollback this migration and run again now your database will have a string column with 8 bytes of size.

If you specify the version in the migration, no matter which version of Active Record you are using the column will always be generated with the size that were the default in the version of Rails that it was generated. In my example, if you specify 4.2 as the version it will be always a 4 bytes string column.

Limit a text column in an ActiveRecord migration 5.0 using the PostgreSQL adapter

t.text produces a text column in PostgreSQL and text doesn't allow for size limits because text is:

variable unlimited length

Since there's no limit supported by the database, the PostgreSQL driver won't look for a :limit option; keep in mind that you're saying t.text(column_name, options_hash) so you can throw whatever you want into options_hash and the driver will ignore anything that it isn't specifically looking for.

If you want to limit the column size then you can either manually add a CHECK constraint (which ActiveRecord won't understand so you'll have to switch from schema.rb to structure.sql) or use a varchar column (AKA t.string):

t.string :body, null: false, limit: 260

Also, your schema.rb is generated based on what is in the database, not what's in your migrations. Since text doesn't support a limit, the database won't know about your limit: 260 option; if the database doesn't know about it, ActiveRecord won't get it back from the database when ActiveRecord is asking the database for schema information.

Ruby on Rails 5.0 Table removal

Although you deleted your git branch and local code, if you didn't delete your database, it remains the same so your table still exists.

You can create a migration to drop a table.
Code from this answer.

rails generate migration DropProductsTable

class DropProductsTable < ActiveRecord::Migration
def up
drop_table :products
end

def down
raise ActiveRecord::IrreversibleMigration
end
end

I don't know what database you are using, but if the table is the same as what you want to add you may not even need to drop it.

Why Rails 5 uses ApplicationRecord instead of ActiveRecord::Base?

While it may seem the same in basic Rails applications, there actually is an important difference once you begin to use rails engines, plugins / gems or direct methods from ActiveRecord::Base.

  • ActiveRecord::Base.include(MyFeatures) mixes in the features directly into ActiveRecord::Base and it is present there forever for all later uses of ActiveRecord::Base (it cannot be "unmixed") and there is no way to get the original ActiveRecord::Base anymore in any code after the include. This can easily lead to problems if some of the mixed in feature changed the default ActiveRecord behavior or if e.g. two engines / gems tried to include same-named methods.

  • On the other hand, the ApplicationRecord approach makes the features present only for the classes (models) that inherit from it, other classes, as well as direct use of ActiveRecord::Base stay pristine, uncluttered by the module features.

This is especially important when engines or rails plugins are used as it allows them to separate their own model logic from the main application's model logic which was not possible before ApplicationRecord.

All of this is also nicely described in this blog post and this github comment.

Error ActiveRecord::PendingMigrationError

Ok the answer is very simple!Just try migrating your DB to version=0 with command: rake db:migrate VERSION=0

and then run rake db:migrate



Related Topics



Leave a reply



Submit