Using open source software is like living in prehistoric ages: you’d better always stay with your mates, otherwise soon you will find yourself alone fighting against the harsh nature trying to survive until one day you will be eaten by a huge carnivore.
That’s what happens with those who are too lazy to keep their web application up to date with Rails. You can find many posts describing the process of migration to Rails 4.0. In this article I’d like to tell you about my favourite changes in ActiveRecord 4.0.
I assume that your Rails version is 3.2 or greater, otherwise you most likely were already eaten.
Since first version of Rails it assumed that you use MySQL to store your data. Steve Klabnik wrote an article about two default stacks used by Rails projects today. Whereas MySQL is well-supported by Rails and its default ORM ActiveRecord, most of PostgreSQL features (like hstores, arrays etc.) were undeservedly ignored. Until Rails 4 came in.
As you may noticed, here at adeven we are big fans of crunching numbers with Postgres. And we
love to have them returned as hashes, that could be easily mapped on value objects. If you had ever tried using hstores
with Rails, I bet you did it with activerecord-postgres-hstore gem
that allows you to use
ActiveRecord::Coders::Hstore serializer for handling hstores. Good news, since Rails 4.0 you
can get rid of this dependency in your Gemfile. You don’t even need to declare your hstore fields as serializable, Rails
is smart enough to detect and properly cast the type of your column.
Moreover, if you have a custom serializer built on top of hstore then you don’t have to manually parse a string with
serialized hash anymore. Just assume the parameter for your
load method to be a hash and it should be returned
as a result of your custom
Consider a serializer class for a field containing an hstore. With
ActiveRecord::Coders::Hstore it could look
1 2 3 4 5 6 7 8 9 10 11 12 13
Since Rails 4.0 it turns into
1 2 3 4 5 6 7 8 9 10 11
Less work for us, right?
Everything is an
Lazy loading of database objects was first introduced in ActiveRecord 3.2. That means that the database will be queried
only when you really need the data. Until then you’re dealing with
ActiveRecord::Relation. This approach plays
well with a streaming feature deferring data extraction until view rendering phase. It was still possible to eager
load the data by calling
all on your scope which implicitly converted your
Starting from ActiveRecord 4.0 this ambiguity has been removed. From now
scoped are deprecated
and you should either explicitly call
to_a on your scope to get an array of results or call
eager-load your data.
That is the change we all were waiting for! Starting from Rails 4 you can make your code more database-agnostic by
replacing pure string conditions with chained empty
1 2 3 4 5 6 7
Scopes must be turned into lambdas
Consider a model that has a scope with datetime
1 2 3
Parameters that will be passed to
where are evaluated at the time when
Post is loaded, which means that
on the next day
Post.yesterday will keep the same records as for today. To avoid this since ActiveRecord 4.0
you have to use lambdas to define scope (as well as default scope) conditions:
1 2 3
Date.yesterday will be evaluated only when the ActiveRecord will call lambda given as an argument to
apply the scope.
Getting rid of “Unknown OID” warning
After I updated our app to Rails 4.0 I got a bunch of warnings saying
Unknown OID: .... It happens when Rails tries
to find out the OID for the column to properly cast the type.
This pull-request gave me a hint that from now you should be more strict
and explicitly define what column type should be expected when using SQL
'column' AS alias statement.
1 2 3 4
Almost all changes in ActiveRecord 4.0 that comes with Rails 4 related to advanced usage of Arel and PostgreSQL. If you don’t have too much logic in your database and if you were doing everything right then upgrading from 3.2 should be pretty smooth and surprise-less.