Upgrade to Rails 2

Hi, I’m a little bit behind the curve I guess. I need to upgrade my
app from Rails 1.2.6 to the most recent version 2.2.2. Are there any
complete guides (including Peepcodes or Pragmatic pdf books) that give
you a comprehensive guide on how to upgrade your application?
Everything from the little changes that you need to make in
development.rb to deprecated methods and how to take best advantage of
new methods? I’ve seena couple short blog posts that hit some of the
major things like @params, form_for and such but I’m still running
into lots of little problems getting my site to even run under 2.2.2.

On Tue, Mar 3, 2009 at 6:57 AM, anrake [email protected] wrote:

Hi, I’m a little bit behind the curve I guess. I need to upgrade my
app from Rails 1.2.6 to the most recent version 2.2.2. Are there any
complete guides (including Peepcodes or Pragmatic pdf books) that give
you a comprehensive guide on how to upgrade your application?
Everything from the little changes that you need to make in
development.rb to deprecated methods and how to take best advantage of
new methods? I’ve seena couple short blog posts that hit some of the
major things like @params, form_for and such but I’m still running
into lots of little problems getting my site to even run under 2.2.2.

Hi, you might want to familiarize your self with the current version of
Rails by reading
the Ruby on Rails Guides located here:

Then you should be able to take that information to migrate your Rails
application.

Good luck,

-Conrad

anrake wrote:

Hi, I’m a little bit behind the curve I guess. I need to upgrade my
app from Rails 1.2.6 to the most recent version 2.2.2. Are there any
complete guides (including Peepcodes or Pragmatic pdf books) that give
you a comprehensive guide on how to upgrade your application?

I did it to several programs like this:

  • edit environment.rb and upgrade the version
  • rake rails:update
  • run all the tests
  • fix one warning or error
  • revert everything in config (leave the new JS)
  • pass all the tests
  • integrate
  • repeat until no more warnings or errors

The point of unit tests and to TDD is to make the smallest changes
possible, and
relentlessly test each change. But upgrading a major version tick is a
big
change, so you must force the upgrade to work incrementally, as a series
of
small changes.

If you get stuck, you can always revert and start again.


Phlip

Thanks guys. I guess I’m not missing any quick & easy guides then.
Will slowly plug away…

2009/3/3 Phlip [email protected]

  • rake rails:update
  • run all the tests
  • fix one warning or error
  • revert everything in config (leave the new JS)

I don’t understand what is meant here. Do you mean go back to previous
version of Rails?
If not then what?

  • pass all the tests
  • integrate

I don’t understand ‘integrate’ in this context either I am afraid.

On Wed, Mar 4, 2009 at 5:59 AM, Colin L. [email protected]
wrote:

@Colin L. - Philip is saying that you do the upgrade and part of the
upgrade process is to
change RAILS_GEM_VERSION in your environment.rb to
the
version that you’re
upgrading to (i.e. 2.2.2). Also, you’ll have to run
the
‘rake rails:update’ to update both
configs, scripts and public/javascripts for your
Rails
application. Now, you’ll be at the
point where you’ll simply execute ‘rake test’ which
runs all unit, functional and integration
tests.

  • repeat until no more warnings or errors

Finally, you’ll continue to execute ‘rake test’ until you have fixed all
the
failing
test(s) within your Rails application.

Good luck,

-Conrad

2009/3/4 Conrad T. [email protected]

version of Rails?
application. Now, you’ll be at the
point where you’ll simply execute ‘rake test’ which
runs all unit, functional and integration
tests.

@Conrad - I got that bit, it is the ‘- revert everything in config
(leave
the new JS)’ that I do not understand.

I found this Peepcode pdf book to be quite valuable. it goes over
some of the deprecations and cool new features for people already
familiar with Rails 1.

https://peepcode.com/products/rails-2-pdf

I did it to several programs like this:

  • edit environment.rb and upgrade the version
  • rake rails:update
  • run all the tests
  • fix one warning or error
  • revert everything in config (leave the new JS)

I don’t understand what is meant here. Do you mean go back to previous
version of Rails?

Yes:

I always always use “revert” to mean “bump files back to where
Subversion (or
Git or Zip or whatever) saw them last.”

Sorry I forgot that some folks have not yet learned that reverting,
early and
often, is a Best Practice in software development!

The point is that code on your bench is invisible to your version
controller
until you “gate” it in, and the only reasonable gate is passing unit
tests. So
to keep mistakes and experiments invisible, you revert them. Then the
version
controller thinks you are awesome, because it only sees good code, and
it never
learns the awful truth about you! (Or about the Rails maintainers :wink:

From the top:

I have upgraded several Rails 1.2.x programs to 2.x, following this
working cycle:

edit environment.rb and tweak the RAILS_GEM_VERSION to ‘2.2.2’

rake rails:update

(commit your new *js files, ALONE, into your version controller)

run all the unit tests

  (if you don't have unit tests, don't start the upgrade until
   you spend a very long time adding them - one for each branch
   in all of your logic. "functional" and "integration" tests
   are also "unit" tests here - the name is just a hint they should
   be higher level...)

if any test fails, or if the code emits a warning…

  fix the problem

  revert your config & scripts folders, so your version is now 1.2.x 

again
(svn revert -R config scripts)

  pass all your tests (and observe your problem remains fixed!)

  integrate to your version controller

now repeat those steps. Bump the version up again, run the tests,
find
one problem, fix it, revert the version, pass all the tests, and
integrate.

@Colin L. - Philip is saying that you do the upgrade and part of the
upgrade process is to
change RAILS_GEM_VERSION in your environment.rb to the
version that you’re
upgrading to (i.e. 2.2.2). Also, you’ll have to run
the ‘rake rails:update’ to update both
configs, scripts and public/javascripts for your Rails application.

Yet I suspect that newer prototype.js versions are generally
compatible with
older rails versions, so I let them slide. rake rails:update will
attempt to
update them, but reverting them every danged time you fix a bug in a
Ruby file
is a PITA.

Now, you’ll be at the
point where you’ll simply execute ‘rake test’ which
runs all unit, functional and integration
tests.

Note that, during my cycle, you could deploy your app to live users. (If
the new
JS works - if not; revert it to the older version!)

  • pass all the tests
  • integrate

I don’t understand ‘integrate’ in this context either I am afraid.

Update your code from the version controller, to get all your
colleague’s
patches. Then pass all the tests, commit the code to the version
controller, and
“outegrate” the code into your colleague’s workstations. Continuous
integration
as also an industry Best Practice (which Rails supports admirably), so
we use
one word for it around here.

2009/3/7 Phlip [email protected]

The point is that code on your bench is invisible to your version

 revert your config & scripts folders, so your version is now 1.2.x

again
(svn revert -R config scripts)

 pass all your tests (and observe your problem remains fixed!)

Do you mean you require that the code runs on the old and new versions
of
rails? Is this always possible? In a recent upgrade I had to change
the
base class for my unit tests from Test::Unit::TestCase to
ActionController::TestCase which I imagine would not have worked had I
reverted. Are there not other cases of code that cannot be made to work
in
old and new version of rails?

Why does it matter whether the code runs in the old version of rails
anyway?

Colin

Colin L. wrote:

Do you mean you require that the code runs on the old and new versions
of rails? Is this always possible?

No. When the Rails maintainers took the default paginator out, and moved
it into
a plugin, they very wisely (not!) decided to upgrade it at the same
time. We
have enough mature code, on mature databases with lots of records, that
we
needed the old paginator more than we needed to rebuild our views. So I
copied
the old paginator out of the old code and crammed it into our lib
folder, and
wired up its helpers. It’s still online like that…

In a recent upgrade I had to change
the base class for my unit tests from Test::Unit::TestCase to
ActionController::TestCase which I imagine would not have worked had I
reverted. Are there not other cases of code that cannot be made to work
in old and new version of rails?

Why didn’t you stay with Test::Unit::TestCase? The point of running the
tests
was to let them tell you what to upgrade. Because the test.rb file still
mutilates Test::Unit::TestCase directly, we did not need to change it
until
after the Final Integration, when we stuck with the higher version
number.

Why does it matter whether the code runs in the old version of rails anyway?

So
all
tests
pass
when
you
integrate!!!

Otherwise you are integrating one huge change, without the ability to
safely
revert in small increments.

2009/3/7 Phlip [email protected]

was to let them tell you what to upgrade. Because the test.rb file still
mutilates Test::Unit::TestCase directly, we did not need to change it until
after the Final Integration, when we stuck with the higher version number.

I forget the exact issue now, but the test would not compile with
Test::Unit::TestCase. Perhaps I could have changed the test code to
make it
work but changing the base class fixed it without changing the test.

                                               integrate!!!

An alternative strategy that has worked for us is to do the mods for the
Rails upgrade on a branch. Merging in changes from the current
master/trunk
is then the equivalent of your integrate phase as it picks up mods done
by
other team members on the master. Only rarely does a test fail after
the
integrate as it requires that a change on the master is not compatible
with
the new Rails. The final release phase is then only the changes
required by
the upgrade and so is not a huge change, and it has been well tested
along
the way.

In fact for a current project I am adopting a different strategy as an
experiment. I have a branch which runs with edge rails. Occasionally I
merge in changes from the current master and retest, then update to the
latest edge and retest. This should ensure that at the next Rails
release a
minimal amount of work is required to release.

I would take some issue with your comment earlier that you should only
commit when tests pass fully. We use git where each user has a local
repository, and there is a master repository which always contains fully
tested code. Each developer runs a local branch on his repository and
is
encouraged to commit often. When he has completed a change and all
tests
run (typically two or three days work) then he picks up the latest mods
from
the master repository, retests and pushes his work to the master. He
then
starts a new local branch for the next phase.

I am not suggesting that this is a ‘better’ way of working, but it works
well for us.

Colin L. wrote:

An alternative strategy that has worked for us is to do the mods for the
Rails upgrade on a branch. Merging in changes from the current
master/trunk is then the equivalent of your integrate phase as it picks
up mods done by other team members on the master. Only rarely does a
test fail after the integrate as it requires that a change on the master
is not compatible with the new Rails. The final release phase is then
only the changes required by the upgrade and so is not a huge change,
and it has been well tested along the way.

Thanks for reminding me we did that with our most important (and
hoariest) app.
While one branch added features, we would merge them over into the
upgrading
branch, and we would merge successful tweaks back.

However the upgrading branch also practiced continuous integration,
mostly with
passing tests. We put return # TODO on a handful of them - the ones we
knew we
could easily fix after crossing the threshold of integrating as Rails 2.

I would take some issue with your comment earlier that you should only
commit when tests pass fully. We use git where each user has a local
repository, and there is a master repository which always contains fully
tested code.

I’m sure that setup could be used for good as well as evil.

Each developer runs a local branch on his repository and
is encouraged to commit often. When he has completed a change and all
tests run (typically two or three days work) then he picks up the latest
mods from the master repository, retests and pushes his work to the
master. He then starts a new local branch for the next phase.

I am not suggesting that this is a ‘better’ way of working, but it works
well for us.

“two or three days work” gives me pause. However, git’s merging system
could to
work very close to the Agile ideal of integrating each refactoring step,
as an
atomic unit…


Phlip