Monday, May 24, 2010

Moving to jackdempsey.me

A final post here at blogger: I'm moving my efforts over to http://jackdempsey.me so if you're interested, please update accordingly. Thanks!

Wednesday, February 3, 2010

notes from yet another rails 3 upgrade

These tips and tricks are valid as of today, February 3rd, 2010. Who knows what next week will bring, but for now, I thought compiling some of the techniques and hacks I've seen might help others.

Rails Related

If you see a "no such file to require: rails/all" you probably don't have Rails installed correctly. I was basing my upgrade on the great screencast produced by Topfunky over at peepcode.com, and his method didn't work for me. To get things running I added this to my Gemfile:

path "/Users/jack/git/rails", :glob => "{*/,}*.gemspec"
gem "rails", "3.0.pre"
gem "rails", "3.0.0.beta" # Just changed today it seems


Obviously, change the path to wherever you have rails checked out locally.

HAML

If you see something like this: Missing template articles/index with {:formats=>[:html]} in view path

you probably need to install haml.


$ haml --rails .


and then you'll likely see an error about html_safe!

Geoff has a nice little idea going with a config/initializers/rails3_hacks.rb file which I've also done. You can drop this in and get by the errors for now:

projects/app master > cat config/initializers/rails3_hacks.rb
class String
def html_safe!() self end
def html_safe?() true end
def safe_concat(value) value+self end
end


WillPaginate

Looks like Mislav and other's have been doing a lot of work in upgrading the plugin. If you see a "no paginate method for Class...." error, try cloning the source down locally, check out the rails 3 branch,build and install that gem and then update your Gemfile:

...
gem 'will_paginate', '3.0.pre'
...

It also seemed that WillPaginate wasn't being required into my app. For now I've created a config/initializers/requires.rb file and dropped in random requires for attention later. Putting a "require 'will_paginate'" in there fixed that up nicely.

Update:
Seems something's broken now. I'm getting this error:

uninitialized constant ActiveRecord::Calculations::CALCULATIONS_OPTIONS

Seems WP relies on that constant without checking for its existence, and it looks like its gone now. Easy enough to quick patch it if you need to get by it, but I imagine it'll be fixed in the rails3 branch soon enough.
Assorted Issues

HTMLEntities doesn't seem to be working, so I commented that out for now. For a great beginning list of what gems should be working, take a look here: http://wiki.rubyonrails.org/rails/version3/plugins_and_gems

Devise: not ready for rails 3 yet. I think they're trying to see what routing changes will settle and how that will affect their code. I'm going to see if I can pop over into that and help out a bit as I'd love to keep using it in this app.

new_rails_defaults.rb: I had an error from this file and realized it's old anyway, so git rm and it's gone.

Passenger

I also overhauled a bunch of other ruby related items on my boxes recently, and one of those items was passenger. After updating to 2.2.9, reinstalling the module, changing RailsEnv to RackEnv, things are mostly good. Remember to point to the right ruby if you're using rvm. I also deleted the config.ru file per their recommendation: "Smart spawning (the mechanism with which REE’s 33% memory reduction is implemented) is *not* supported for Rack apps. This means that if you want to utilize smart spawning with Rails 3, then you should remove your config.ru file."

I think that's it for now. I imagine I'll update this page as I deal with new issues. Pretty excited about the new changes and starting to actually make use of them.

Update

Previous notes were from my macbook pro. Now that I'm back on the iMac I'm finding other issues. Latest is:

/Users/jack/git/rails/activesupport/lib/active_support/dependencies.rb:167:in `require': no such file to load -- rails/commands/rails (LoadError)

I'm actually not sure if that was something I did as it looks like its definitely just "require 'rails/commands'" in the latest source, but either way, if you're seeing that, just take off the second rails in that line. Correct line should be:

require 'rails/commands'

at the end of your script/rails.

Bundler

Somehow just found myself facing this:

projects/app master > bundle install
/Users/jack/.rvm/gems/ree-1.8.7-2010.01/bin/bundle: line 1: require: command not found

A quick cat and I see something's changed, no #!...ruby line to see. Realized I had bundler 0.9.0 and 0.9.0.pre4, so I uninstalled them both, and reinstalled with:

$ gem install bundler --pre

and now have bundler-0.9.0.pre5 installed.

Still things are borked, but it seems its a result of github being down: "Page did not respond in a timely fashion."

Will try again in a few to make sure this gets me back on track.

Update

Ok, github's back, and just saw a tweet from Wycats. Looks like 0.9.0 final is out now, but it's recommended to wait til tomorrow and 0.9.1 + some docs. YMMV.

Application != ApplicationController

So, the app I'm converting was originally written in Merb, was partially converted to Rails 2, and is now on its way towards Rails 3. In this transition I've generally remembered what pieces to change from Merb to Rails, but I had a nice stumble earlier in forgetting to change a controller. So, if you find yourself in a place where you have a route that you know works, but is not recognized, make sure your controller is named whatever_controller.rb, and contains the code:

class WhateverController < ApplicationController
...
end

not "< Application". You'll an error about a route missing and could easily spend a couple hours missing the obvious.

Routes

I keep tripping myself up with this. Lets say you have a route defined as:


match 'foobar/:foobar' => 'foobar#foobar', :as => :foobar


These calls will all fail:


ree-1.8.7-2009.10 > app.foobar_path
ActionController::RoutingError: No route matches {:action=>"foobar", :controller=>"foobar"}
... from (irb):3
ree-1.8.7-2009.10 > app.foobar_path('')
ActionController::RoutingError: No route matches {:use_defaults=>false, :action=>"foobar", :foobar=>"", :controller=>"foobar"}
... from (irb):4
ree-1.8.7-2009.10 > app.foobar_path('test')
=> "/foobar/test"


until that last one which passes in a value. This makes sense, as the route defines foobar as a requirement, and not passing in a value is an 'error'. It's a little less obvious that an empty string doesn't satisfy it to me, and definitely not obvious when you have this in a loop and an object just happens to be missing its value for foobar.

One way around this is to make the :foobar piece optional, and handle that reality in your controller elsewhere. You could also protect against this by checking that object.foobar exists in your loop, and not linking unless it does.

I've also just realized that for a certain route of mine, one that passes in domain names, sending in 'euraeka.com' will result in an error. I'm not sure if this is the recommended solution, but its letting me progress for now:


match 'domain/:domain' => 'search#domain', :as => :domain, :domain => /.+/


I'm using domain here instead of host as I think host might be reserved somewhere. Couldn't seem to get it to work before, so if you're having that issue, let me know.

Saturday, July 18, 2009

getting started with ruby 1.9

Yehuda Katz has a nice post over at his blog talking about Ruby 1.9 and what we need to do to move our community towards it.

Lots of great points are brought up, but for me, the biggest issue is just not having the time to fiddle with things, setup nice little aliases, etc. Thankfully, one of the nice guys over at Relevance has done this for us: spicy-config

On a quick side note, Chad's configs also helped me get up and running with zsh, and that's been a whole other fun trip.

You'll want to clone his repo and take a look in at his .zshrc file along with the ruby_installer and ruby_switcher files inside .zsh. All you have to do is source the files to get the functions defined, and run what you're interested in. I did set things up a little different given that I don't use the Leopard install of ruby...but if you're reading this, I assume you can see what you'd want to change if need be.

That's about it. I can now say "use_ruby_191" and it quickly switches me over, and then 'use_ruby' to jump back to 1.8.6.

Great stuff Chad, thanks!

Thursday, July 16, 2009

a couple quick git tips

The other day someone asked in #git how to fix something in the middle of an unsuccessful rebase. So, I thought I'd rebase some of my own code, reorder things so there must be a conflict, and then try to duplicate their question.

Only problem was that there was no error, and I hadn't really paid attention to which commits I reordered. Thankfully, I got a bit of help from a gent named doener.

I'm including a rather long gist showing the process. Basically, git reflog is your friend, and you should play with this at some point in a test repo like I've done here.

Note: anytime you git reset --hard be very sure and confident of what you're doing.

Thursday, July 2, 2009

Opening your mind with Clojure

I know, I know, clever title, right? It's true though--I've taken the last week or so to take a stab at learning Clojure. I've played with functional languages before, but unfortunately "play" is about as far as I've gotten. This time it was different. I actually made it all the way through Programming Clojure (Pragmatic Programmers), which is saying something (I'm king of "Oh, I'll buy THAT book too!" and never finishing it...). There are a variety of reasons I'm really enjoying Clojure, but for now I'd like to offer some tips in getting set up.

Getting the Source



Rich Hickey is the guy behind Clojure. I'd call him a mad genius, except he seems pretty nice and "happy genius" doesn't really work...Anyway, he's recently agreed to move the project to github, and you can find the two main sources you'll want in his account there. Using the wonderfully helpful github gem you can clone things down with


gh clone richhickey/clojure
gh clone richhickey/clojure-contrib


At this point I'm assuming you've got java installed and working, which may be a big assumption, but I don't have the heart to tackle that mountain today.

So, get into the source and start compiling:


cd clojure
ant


If all goes well, you should have some nice jars all sparkling and ready for use. Now for contrib:


cd ../clojure-contrib
git checkout 3073f0dc0614cb8c95f2debd0b7e6a75c1736ece ***
ant -Dclojure.jar=../clojure/clojure.jar


*** At this point in time, you need this revision to compile against clojure 1.0. I imagine this will change over time, but if you have any problems with compilation, a good place to check is the #clojure channel.

You need to pass in that -D flag so we can use the clojure.jar in compiling clojure-contrib. Once this is done you'll want to put the jars into a common place where java can load them up. I've created an /opt/jars directory on my system, and so I'll drop them into here.

Now, you'll want to make sure the CLASSPATH variable is setup correctly, and it took me a while to do this the first time, so here's a hint:



I think newer versions of java will just let you specify the main directory name. This is for java 1.5 which I somehow seem to still be running.

Almost there!

Setting up a clj file



I've blatantly stolen this file from Chouser, an ever present and extremely helpful soul found in #clojure (he's like Illari of #git for those who frequent that channel...if I ever get rich, a fat check is in their future).

This is what the clj file looks like:



If you're on OS X you'll want to install rlwrap:


sudo port install rlwrap


You'll also want an init file to help load up some useful functions like 'show' into your REPL. Create a file named "repl-init.clj" and put something like this inside:


(set! *print-length* 103)
(set! *print-level* 15)
(use '[clojure.contrib.repl-utils :only [source show]])
(use '[clojure.contrib.stacktrace :only [e]])


This should be executed by your clj script on startup, and setup things automatically for you.

Wrap-up



So that's about it for now. I'm having a great time so far, and honestly the hardest parts are getting your environment setup and keeping it up to date. If you're used to java development then this should be a breeze. Having been away from it for years, it took me a while, and hopefully this will save others that same pain.

Thanks to Paul Barry and Aaron Bedra for getting me interested in Clojure at Ruby Nation, and of course Rich et al for all the time and energy put into developing this great new language.

A few links



clojure.blip.tv - Rich gives some great presentations, and many of them are captured here.
clojure.org - Lots of great documentation here
#clojure on irc.freenode.net - over 100 clojurists and clojuristas. Very helpful and friendly.

Saturday, December 13, 2008

merb and sequel

Recently I needed to order some records by a mathematical formula, and I couldn't figure out a way to do it in DM (although it looks like the idea was well received and might make it into a future relase). I'd heard some great things about Sequel, so I decided to take a look and see what possibilities I had there.

If you haven't read anything about Sequel, head on over to its rubyforge page at http://sequel.rubyforge.org/documentation.html. There's a good amount of information from basics to how you can implement complex associations between models. There's even a link to Lori Holden's MerbCamp presentation.

Sequel piqued my interest in many ways: it uses the Active Record Pattern to create methods from column names, but you can also do a more DataMapper style definition of columns inside your model:



You can use Post.create_table! as a sort of automigrate (it will drop and recreate the table). The usage of set_schema is more for test code and experimenting, and I found it very useful when developing sequel_polymorphic and sequel_taggable.

So, while its easy enough to generate a new merb core app and customize it as you like, if you're going to be generating a lot of apps with the same configurations, its worth learning how to build a stack. Currently its mostly a manual process: you build a gem with a certain structure by hand, and then use your stack with merb-gen. Eventually this will probably be an easily streamlined process, but for now its still up to you to put things together. You can read more about the structure here and take a look at merb-sequel-stack as well.

If you're looking to get a bit closer to your DB and want a lot of flexibility and power, you should really take Sequel for a test drive. Its current maintainer, Jeremy Evans, has been a ton of help with answering dozens of questions in #sequel, even when its to answer something he doesn't agree with like polymorphic associations, which I'll go into next time.

Monday, December 1, 2008

a possible addition to www.builtbythenet.com

The same questions get answered many times a day in #merb and I have to think there's a better way, especially for dependency issues. Whether is a rubygems issue, one with Merb or any of the typical libraries people use it with, or just some random little bug you only see on windows, I haven't seen a good way to track and relate all of this information. Some goes on a wiki, some is remembered and routinely typed back by various people in #merb, some goes to the mailing list. It shouldn't have to be this way, and I'm hoping this idea will help:

dependency hell mitigator

The implementation would be dead simple, probably something like a tag cloud. It'd rely on people entering info and trying to keep things up to date...but hopefully this would result in a more organized and useful collection of all the various tricks we employ to get through those moments of keyboard tossing and mice bashing.

As usual anyone interested in coding this up is more than welcome to--the source is at jackdempsey/builtbythenet If enough people like this idea then I'll probably start in on it myself at some point and see where it goes.