Rails 2.x to Rails 3

6 Oct

Today I’m starting on upgrading my Rails 2 project to Rails 3 and I thought I’d put all the changes I need to make to get it working here incase anyone runs in to the same problem(s).

Prepping for this shit

I made sure I had the following tools before I started (this step is VERY important):

  • Enough Coffee
  • Get EVERYONE out of the house (Make sure your girlfriend or wife isn’t around. Porting Rails 2 to 3 may in some cases be bad for your relation ship due to shouting, cursing and/or throwing stuff at her)
  • Headphones
  • Good music — I prefer the following: DI.fm dubstep
  • Porn (If that’s what keeps you calm! Hey I’m not saying I’m watching it .. but, you know, if that’s your thing go for it!)

My gems:

Before I started I checked my environment for gems and made sure they were working with rails 3 and moved them over to the new rails project in to the Gemfile. The project uses the following Gems (=> Replaced with):

  • pluginaweek-state_machine
  • validation_reflection => removed
  • authlogic => devise
  • searchlogic => meta_search
  • compass => more/less
  • haml => removed
  • formtastic
  • will_paginate
  • inherited_resources
  • responders
  • has_scope
  • hpricot => nokogiri
  • gruff => removed
  • rboss
  • exception_notifier

Errors Problems (notes)

The problems I’ve run in to are none so far:

SASS to Less

This is an absolute pain, I swear. I haven’t been able to find a tool which can convert SASS to Less so I have to do everything by hand (If at this point you’re thinking, DUDE, you stupid fuck use XXXX for that or use XXX regexp for that. Then please do share!). I did came up with this Regexp which should make it a little bit easier if you’re using TextMate (or any other editor):

Find:

/^(\s*):?(\S*)([\s\S*]*)/i

And replace:

$1$2:$3;

All you have to do by hand is add de brackets around your classes and IDs

Active Record — Custom select

I have the following scope with a custom select:

scope :include_matches_count, lambda {
select("organizations.*, SUM(spider_webs.matches_found) AS spider_matches_found").
joins("LEFT JOIN orders ON organizations.id = orders.organization_id LEFT JOIN spider_webs on orders.id = spider_webs.webs_id AND spider_webs.webs_type = 'Order'").
where('(spider_webs.id = (SELECT id FROM spider_webs AS n WHERE n.webs_id = orders.id AND n.webs_type = "Order" ORDER BY n.id DESC LIMIT 1) OR 1 = 1) AND organizations.customer_id = ?', User.current.customer_id).		group('organizations.id')
}

If you would call this scope (say my model is called `MyObject`) MyObject.include_matches_count.empty? You’ll get the following error:

undefined method `zero?' for #

Hmm now that’s odd. Up on close inspection I noticed I had a very strange select in my console output:

SELECT COUNT(*) AS count_all, organizations.id AS organizations_id FROM `organizations` LEFT JOIN orders ON organizations.id = orders.organization_id LEFT JOIN spider_webs on orders.id = spider_webs.webs_id AND spider_webs.webs_type = 'Order' WHERE ((spider_webs.id = (SELECT id FROM spider_webs AS n WHERE n.webs_id = orders.id AND n.webs_type = "Order" ORDER BY n.id DESC LIMIT 1) OR 1 = 1) AND organizations.customer_id = 3) GROUP BY organizations.id

Huh? Where did my custom select go to? So I checked the rails code and it seems that if the object hasn’t been loaded before .empty? is called, Rails decides to just call count.zero? on the object. Ignoring your select and causing this error.

So if you have a custom select in a scope and you would like to check if the result is empty before displaying it make sure you call “.all” on it first:

MyObject.the_scope_with_a_custom_select.all.empty?

updating while I’m on the train.

Ruby on Rails queueing gem: Runner

4 Oct

A week or so back we started porting projects to Rails 3 and all new projects were created using Rails 3. The project that I was working on (name irrelevant) needed some sort of concurrency. In the past we already tried a few existing Gems but there was always something missing or there was simply too much of something. Is most cases it was also hard to customize the gem or it simply didn’t live up to our expectations.

In the past we had also tried to create our own concurrency implementation but these either-way failed or were just too specifically designed. If you wanted to do something else than the feature it was designed for; you would have to rewrite parts of the code. You may call this design error, but it was simply not the intention to create a flexible concurrency implementation.

So our search for a new concurrency Gem went on; we tried two and came to the conclusion we would have to write something our self. I was given the task to create a new Gem. A new concurrency (queueing) Gem which would have to be flexible, maintainable and would have to be not as specific as we have been in the past. Or in fact this concurrency Gem had to be able to do all sort of tasks. From sending out mails to importing users from a CSV file.

I’d tried delayed_jobs and liked their implementation very much. The one thing we all agreed at here at the office was we didn’t want to have a separate Rake task which would require to be run in order to do some sort of concurrency. We wanted to be able to have the task been done within the application with whatever concurrency we specified; be it Forking or Threading or a simple yield, it all had to be possible. So with delayed_job in mind I started to design the Gem and came up with the name Runner (obvious name!).

I took me two days to implement a very basic version of the Gem. The only thing it could do back then was fork a method in the background without the need of an additional Rake task. At the current time of writing it has the following features:

  • Supports various implementations of Concurrency (forking, threading and yielding. But the last isn’t really concurrency)
  • Developers using the Gem may add different kind of concurrency to gem by simply giving the concurrency class the Runner initializer
  • It has the ability to queue tasks which means you more or less park the tasks for later.
  • It may immediately run tasks in the background using the various concurrency methods.
  • Threading tasks requires no changes to your current classes.
  • Extending the backend (currently comes with ActiveRecord) only requires you to implement database specific code (scopes, etc.)

Continue reading

Name change — Spiced Ruby

29 Sep

As you might have seen I’ve changed the name of the blog from Spiced Cocoa to Spiced Ruby. Simply said; I’m probably not going to blog about Cocoa anymore because I’m most likely no longer going to do any major development in the Objective-c/Cocoa area.

It somehow saddens my heart to do it though, I mean I had some good times with Objective-c and a couple bads. I’ve honestly also lost a little interest in Objective-c. Yes, Objective-c. Not Apple development as a whole. I’m hoping it will be possible to get Ruby to the iPhone in the near future. So please for love of god Apple get Ruby to the iPhone, hot-cocoa is awesome!

Anywho, I hope some of you will stick around for Ruby’s sheer awesomeness!

The Power of Ruby: Metaprogramming Part one

25 Sep

Part one: Understanding Ruby

Meta programming, who hasn’t heard of it these days? You see it everywhere, you perhaps do so your self without even knowing. But what exactly is this thing called Metaprogramming. In Ruby; it’s probably you best friend. And if it’s not, I’m pretty damn sure it will be! It’s hotter then your girlfriend or perhaps your boyfriend. Hell, it’s probably even hotter then your sister hottest girlfriend and that other girlfriend .. well you catch my drift! But in all seriousness it’s somewhat makes Ruby the awesome programming language as it is. But before we can actually use metaprogramming in language, you must understand the very basics of how Ruby works. Continue reading

Ruby on Rails Concurrency Gem

24 Sep

I’ve just released a very alpha version of my Ruby on Rails concurrency Gem, Runner. The syntax is simple and doesn’t require any blocks. For example you could run a method in the background with as simple as:

Klass.spawn.my_method

Which forces “my_method” to be executed in the background.

Queue’ing methods

With Runner it’s also possible to queue calls which will be executed at a later given time. For example you would like to do some very CPU intensive, long running method to be executed daily at 12AM:

class User
def takes_long_time
2 + 2 # I 'm not kidding!
end
end

# somewhere in your code:
user = User.new
user.spawn(:method => :queue).takes_long_time # => The method is now queued and won't be run

# In a rake task witch is run by cron at night
runner = Runner::TaskSpawner.new
runner.start_handlers # => All queued tasks are now being forked and run asynch in the background

For more information and features about the Gem please go to the github repo.

Ruby 1.9.2 released

19 Aug

Yoki Sonoda has just announced the stable release of Ruby 1.9.2!

== About Ruby 1.9.2
Ruby 1.9.2 is mostly compatible with 1.9.1, except the
following changes:
* Many new methods
* New socket API (IPv6 support)
* New encodings
* Random class that supports various random number generators
* Time is reimplemented. There is no longer the year 2038 problem.
* some regexp enhancements
* $: no longer includes the current directory.
* dl is reimplemented on top of libffi.
* new psych library that wraps libyaml. You can use the library instead
of syck.
More details to be found here and here
It has been verified that 1.9.2 works on; Windows (32 and 64 bit  version as well as mingw 32), FreeBSD 6, MacOSX 10.5 (intel and 10.6, Solaris 10 and Symbian OS.
Let’s hope Rails 3 will get released this week too! :)

WANTED: Ruby on Rails Developers

19 Aug

No, this ain’t some cheap ass ad campaign, this is an actual call for ruby developers interested in a job. The company that I currently work for is in a dire need of 2 new Ruby (on Rails) developers and asked us if we knew anyone or if we could be on the look out.

So if you live in the Netherlands and happen to be somewhere near Hoofddorp, and you like .. no, absolutely love ruby then perhaps this might actually be a job for you! For more information you could look on our website and apply if you’re interested.

Continue reading

Objectiveresource does it need rails?

15 Aug

A couple of days back I was looking over my Blog Stats and an interesting search query came up:

objectiveresource does it need rails?

This query got me interested in trying out Objective resource without rails, and technically it should be possible because ObjectiveResource just requires the fetched XML to be in a specific format. So what we can do is create a simple XML document in the same format as Rails out puts its XML. And while we’re at it, let’s create a simple webserver which outputs the XML (honestly I just don’t have Apache working here on my laptop and I seriously can’t be arsed to set it up, and its way too much fun to create a simple Ruby webserver.). So let’s get started!

Continue reading

Installing RVM, Ruby 1.9.2 and Rails 3 RC2

14 Aug

So you want to try ruby 1.9 and rails 3? Awesome! You’ve come to the right place. Before installing ruby 1.9 or rails 3 you want to install RVM (Ruby Version Manager). RVM is a handy tool which allows you to have multiple version of Ruby installed on your system (along with gems, which include Rails).

RVM — Ruby Version Manager

Straight from the RVM Website:

RVM is a command line tool which allows us to easily install, manage and work with multiple ruby environments from interpreters to sets of gems. RVM itself is easy to install!

I couldn’t have explained it better my self. So let’s get started! In order to install RVM just download the gem
sudo gem install rvm

Continue reading

Obj C + Cocoa vs everything else

11 Aug

I haven’t written anything for quite a while, mostly because I simply had nothing interesting to write about. Or at least nothing interesting about Cocoa or Objective-C. The last couple of weeks I’ve been doing less than the usual amount of Objective-C and/or Cocoa. One of the reasons is work and partly because I’ve been lazy. With lazy I’m not saying I haven’t done any programming or reading about programming languages at all. Work has forced me in doing more Ruby/Ruby on Rails simply because the projects I’m on had higher priority than the iPhone apps. And to be fairly honest; I didn’t mind at all.

Continue reading