Shoulda Macro for acts_as_tree

I love writing tests and I love Shoulda.  Here is an acts_as_tree macro I threw together.


class Test::Unit::TestCase

  def self.should_act_as_tree(opts = {})
    klass = self.name.gsub(/Test$/, '').constantize

    foreign_key = get_options!([{:foreign_key => 'parent_id'}.merge(opts)], :foreign_key)

    context "To support acts_as_tree" do
      should have_db_column(foreign_key).of_type(:integer)
    end

    should "include ActsAsTree methods" do
      assert klass.include?(ActiveRecord::Acts::Tree::InstanceMethods)
      assert klass.methods.include? "root"
      assert klass.methods.include? "roots"
    end
  end
end

Popularity: 18%

Notes On Upgrading To Rails 2.3

I am upgrading from Rails 2.2.2 to 2.3.2 on a project today.  Here’s what I’ve found so far.

  1.  RAILS_ROOT/app/controllers/application.rb has been renamed to application_controller.rb.  Upon upgrading if you see /usr/lib/ruby/gems/1.8/gems/activesupport-2.3.2/lib/active_support/dependencies.rb:443:in `load_missing_constant':NameError: uninitialized constant ApplicationController, that’s the change you need to make.
  2. Test::Unit::TestCase is now ActiveSupport::TestCase. The error you’ll see is undefined method `use_transactional_fixtures=.
  3. Using fixture_file_upload stops working unless you include ActionController::TestProcess.

More as I find them…

Popularity: 28%

Add An RSS Auto-Discovery Link in Rails

This is a follow-up to another RSS post I have. Once you’ve created an RSS feed for your site you should create an auto-discovery link for it so that browsers and RSS readers can find it.

Don’t know what I’m talking about? Go to pretty much any blog with a feed (in a somewhat recent browser) and you’ll see a little RSS icon in the address bar or toolbar if the browser auto-detected the feed .

Here’s an example from Firefox 2:

Firefox RSS Icon

Here’s IE7 (when the little star thingy appears, it’s found a feed):

IE RSS Icon

Browsers and readers know the feed is there because in the <head> of the page there is a <link> tag telling it the feed is there.

It looks like this:

<link rel="alternate" type="application/rss+xml" title="My Site's RSS Feed" href="http://mysite.com/feed/" />

Of course, you could just hard-code the tag into your Rails layout, but that’s not a good idea. A better idea is to use the Rails’ auto_discovery_link_tag view helper to do it. The helper method docs can be found in the ActionView::Helpers::AssetTagHelper module.

What you end up with is something that looks like:

<%= auto_discovery_link_tag(:rss, {:controller => "controller_name", :action => "feed", :title => "My Site's RSS Feed"}) %>

See the docs for the full details.

There are other helpful methods on that module too. There’s a method for creating stylesheet links and methods for creating paths to javascript files and images.

Popularity: 45%

Rails Command ‘Ruby Path’ Option

On my Mac the Rails’ default path for Ruby is /System/Library/Frameworks/Ruby.framework/Versions/1.8/usr/bin/ruby. This becomes an issue when copying code to UNIX/Linux servers where /usr/bin/ruby is default path. Fortunately, Macs have a symbolic link ruby -> ../../System/Library/Frameworks/Ruby.framework/Versions/Current/usr/bin/ruby.

You can set the path to /usr/bin/ruby using the -r option to the rails when creating your app: rails -r /usr/bin/ruby <myappname>

Popularity: 40%

Generating RSS in Rails

Generating RSS in Rails 2 is pretty easy.

In the simplest case, all that is required is an extra view file to create the RSS output.

Consider a simple (RESTful) blog example:

route.rb:

...
map.home '', :controller => 'posts', :action => 'index'

map.resources :posts
...

posts_controller.rb:


def index
  @posts = Post.find(:all)
end

When I generated the posts controller, Rails created an ‘index.html.erb’ file for the index action.  It’s an ugly file name, but it helps Rails figure out what to do: ‘index’ is the action, ‘html’ and ‘erb’ are the format and builder to use.  To generate RSS we want to use the XML Builder, so the file name to use is ‘index.rss.builder’. And the file contents should look something like this:


xml.instruct! :xml, :version => "1.0"
xml.rss :version => "2.0" do
  xml.channel do
    xml.title "My Blog"
    xml.description "My Fantastic Blog"
    xml.link posts_url

    for post in @posts
      xml.item do
        xml.title post.title
        xml.description post.content
        xml.pubDate post.created_at.to_s(:rfc822)
        xml.link post_url(post)
      end
    end
  end
end

Now that is really easy, but I’ve experienced two issues with this.

The first issue is with layouts. If the controller uses a layout for all actions (using layout => "mylayout") it will cause Rails to look for a layout file named ‘layouts/posts.rss.erb’. This can be bypassed by excluding the layout for the rss format, like so:


def index
  @posts = Post.find(:all)

  respond_to do |format|
    format.html
    format.rss  { render :layout => false }
  end
end

The other issue I experienced was with the will_paginate plug-in where my index method looks like this:


def index
  @posts = Post.paginate(:per_page => 10, :page => params[:page])
end

The problem is that only 10 posts will show up in the RSS feed, which is not what I want.

There are at least two good ways I came up with to deal with this issue. The my preferred way is create a new feed method that is excluded from the layout and returns all posts.


def feed
  @posts = Post.find(:all)
end

with a new route:


map.connect 'posts/feed.:format', :controller => 'posts', :action => 'feed'

The second way examines the request format and grabs the posts via paginate for HTML and find for RSS


def index
  if request.format.html?
    @posts = Post.paginate(:per_page => 10, :page => params[:page])
  else
    @posts = Post.find(:all)
  end

  respond_to do |format|
    format.html
    format.rss  { render :layout => fals }
  end
end

I like the first way better. Seems a little cleaner. I like small methods.

Popularity: 100%

Apple, Wireless & the Environment

Pathetic as it may seem, I actually read (and refreshed repeatedly) a live blog-cast of Steve Jobs’ keynote at MacWorld yesterday. Later in the day I watched the video on Apple’s web site. I’m a geek, I know. Overall, the press response seemed ho-hum. It’s tough to top the iPhone, but I was excited.

As a loyal Mac owner I was very pleased to see how advanced Apple is in it’s thinking about wireless technology. The Time Capsule is a no-brainer. The wireless backup should have been part of Time Machine from the start. It was, I believe. Early Time Machine literature made it seem that you could wirelessly backup since the Airport Extreme allows you to wirelessly share a hard drive. The cynic in me believes it was yanked from Leopard because Apple decided there was more money in a new product opportunity.

The MacBook Air was the big news. More exciting to me than it’s slim size is its lack of an optical drive and an Ethernet jack. The MacBook Air is a purely wireless machine (save for its power cord). Apple is way ahead of the industry here. It will be a long time before the optical drive and wired Ethernet go the way of the floppy drive, but it’s a start. The MacBook Air is geared towards those that travel a lot and use their laptops on WiFi at home, in airports, hotels and coffee shops. That actually describes me pretty well, but I’m not going to run out and buy one, probably ever. I, perhaps mistakenly, consider myself a power user and like the extra power of my MacBook Pro so I don’t mind the extra size.I was also excited about the new multi-touch gesture support. When I played with my brother’s iPhone I asked myself why my trackpad couldn’t pinch, expand and swipe. The MacBook Air does all that and more. I assume the next generations of the MacBook and MacBook Pro will have the new gesture support too.

The last thing, which I haven’t seen much written about, was the new environmental features of the MacBook Air. I was very dismayed when I read Greenpeace’s Green Electronics Guide in early 2007. Apple didn’t fare well. But since then they have been improving. On a ten-point scale they’ve gone from a 2.7 (yeesh!) to a 6. Not bad. I guess in addition to receiving a MacBook Air through the interoffice mail Steve Jobs received the memo that there’s a lot of money to be made with green products these days.

Jobs stated that the MacBook Air’s case made entirely of aluminum and is entirely recyclable. Bravo. He also stated that all the circuit boards are free Brominated Flame Retardant (BFR) and Polyvinyl Chloride (PVC). BFRs and PVC are toxic chemicals capable of polluting during their entire life-cycle: manufacture, during use and during recycling/disposal. This does not mean, however, that the MacBook Air is entirely BFR and PVC free. Just the circuit boards are, but in writing this post I discovered that Apple has pledged to be BFR- and PVC-free by the end of 2008. Cool. Additionally the MacBook Air’s display is mercury-free (good riddance!) and made with arsenic-free glass. Way to go Apple. My hope is that that their score of six won’t be a six much longer. I look forward to more environmental improvements from Apple. For more info, they keep an environment page on their web site.

Towards the end of his talk Steve Jobs bragged that if they have this many innovations two weeks into the new year, imagine what the next fifty will be like.I can’t wait.

Popularity: 36%

Machu Picchu


Machu Picchu
Originally uploaded by ToddSiegel.

We’re back in Cusco after our four-day trek to Machu Picchu via the Inka trail. Our original plan was to take one of the two alternative trails to Machu: Lares or Salkantay. After hearing the description of the Lares it didn’t interest us and we were told by a few people the the Salkantay was too muddy and dangerous during the rainy season (which is now), but that they would take us anyway. It’s tough to tell in Peru when people are telling the truth or giving you a sales pitch. It was pretty obvious that most guides and tour operators wanted us to do the Inka Trail. I imagine that since this is the slow season they’d rather just put everyone on the Inka trail to make life easy. Since we weren’t sure, we decided to do the Inka Trail just in case the Salkantay was too muddy. It didn’t seem worth the risk. Also, the Inka Trail just re-opened after being closed for cleaning and maintenance for all of February and since it’s the slow season so we figured it would be cleaner and less crowded then other times during the year. It was indeed, very commercial, and a little crowded. There were twelve hikers, along with ten porters and 2 guides, making us a small army. Everyone in our group was really nice. It was a fantastic dynamic. We had people from all over the world: Canadian, German, Australian, Belgian, Argentinian, and us gringos.In some ways, this trek was even more taxing physically than the one in Santa Cruz. The second day was a gruelling five hour ascent to a pass 4200 meters up in the mountains, and then another hour and a half down to our campsite over a stone path that made my knees ache. The third day was a nine-hour rainy trek-a-thon, with visits to several different ruins. Our last day we woke up at 4 in the morning to try and catch the sunrise over Machu. We made it to Machu by 7:30 after sunrise, but before most of the tourists arrived. We spent several hours, in relative peace and quiet, exploring the ruins and enjoying the beautiful mountains surrounding the city.Around lunch time we went down to Aguas Calientes for lunch and to tend to our aching muscles in the thermal baths (hence the name of the town).Today we’re taking it easy back in Cusco and leaving to night for Puno on the Peruvian side of Lake Titicaca.I must confess that ever since I was a kid and first heard the name Lake Titicaca that I’ve wanted to visit. I mean, come on, Titicaca! In a few days we should be in Bolivia.I’ll keep you posted.

Popularity: 35%

Cordillera Blanca

Sharon and I are wrapping up the Cordillera Blanca in the Andes tonight and taking a bus back to Lima to catch a plane to Cusco and Machu Picchu. The Cordillera Blanca is the second highest mountain range in the world, next to the Himalayas.

Our mission here was a hike called Santa Cruz, which goes through a 4750-meter (15,583 ft) high pass in the mountains called Punta Union. Because of the extreme altitude we took a couple of days in a city called Huaraz to adjust.

Locals suggest short day hikes on the outskirts of town to help adjust to the altitude. We started up a trail in the east edge of town called Rataquenua, which is supposed to provide a great view of the town. We never got to the top. We turned around part of the way since some mean looking storm clouds were rolling in, but not soon enough. We got caught in a hail storm during our retreat and I caught a huge one right on the bridge of my nose.

The next day, the day before our hike, we went to see some pre-Incan ruins, called Wilcahuain, outside of town. We took a combi (bus) up to the ruins and decided to walk back. Shortly after we left the ruins we passed a funeral party and they invited us to join. The people we met were all campesinos (as the local indigenous people are called) and were very friendly. We stood around drinking beer, chatting with everyone. They all wanted to meet the gringos. They taught us some Quechua, most of which we forgot (remember there was beer involved) and after a little while we were on our way.

We didn’t make it too much farther down the road before we came across a party for carnaval. I am not sure if this party is typical of just this region, all of Peru or South America, but it goes something like this: everyone drinks chichaand beer, dances in a circle around a tree while throwing talc at each other. After a while people start taking turns hacking at the tree with an axe. Once the tree falls over everyone goes and eats cuy. Sounds strange, right? It was. But we had a ton of fun!

Friday morning we set out in a very cramped combi, with our guide Roger, for a town called Vaqueria where the trail head is for the Santa Cruz trek. Actually, we started where most people finish. We found out after that this is the harder way to go.

The Cordillera Blanca is magnificent. All around are jagged, snow-capped peaks and in the valleys are beautiful blue and green lakes and rushing rivers. All throughout the hike the scenery kept changing, there were lush green mountains and valleys, big boulders, views of glaciers, jagged rocky mountains, streams, waterfalls, rapids, forests and rainforests, cacti, roaming animals and more! Every thirty minutes there was something new to see. It also covered every season of the year. We experienced cold, heat, rain, hail, clouds and wind.

Here are some highlights:
Day One - We started out from Vaqueria, a very poor farming village in the mountains. Children from the village were following us, asking for food. It was heartbreaking. They are so poor and sick. We gave what we could, but more children kept coming, and we were only carrying enough food to snack on during the hike. After the first hour we entered the first valley on our way to Punta Union. The first day’s hike was short - we arrived to our first campsite after three hours.

Day Two - This was the toughest day. Four hours up to Punta Union, and then 2.5 hours down to the next campsite. As we got higher in altitude and the air got thinner, it got more tiring and we had to take more frequent breaks. The ascent was very challenging but very beautiful. Once we reached Punta Union, the valley on the other side of the mountain was even more beautiful than the one we just came from. 15,583 feet!!!! We were exhausted from the climb, but the beauty of the vista re-invigorated us for the rest of the day’s hike. And then we got hailed on…

Day Three - Day three was pretty flat and muddy. We hiked through the valley all day and had beautiful mountain views. As we continued, the valley closed in on us, making the mountains seem taller and more imposing. We hiked for about five hours and set our camp right by the river that runs through the valley. Shortly after arriving at our campsite, it started to rain and continued for most of the night.

Day Four - This day was short but challenging. We walked mostly downhill over loose rocks and through slippery streams that were fed by the waterfalls pouring over the mountainside. After two short hours, we arrived in Cachapampa, a beautiful farming village at the end of the valley. The drive through the mountains back to Huaraz equalled the preceding days in beauty. We drove along a dirt road barely cut into a steep mountainside with a view of other mountains and the farms in the valley below.

Tonight we are headed to Cusco and Machu Picchu. To see pictures of our hike go to http://www.flickr.com/photos/toddsiegel.

Popularity: 34%

In Perú

Last Sunday night I arrived in Lima and met Sharon at the airport. We spent only two days and that was enough. It’s a nice city, but it’s a city, so we took an overnight bus to Huaraz in the Cordillera Blanca in the Andes. Tomorrow morning we are doing a four day trek though the mountains. Hopefully I’ll have more pictures to upload that has been a problem thus far due to various technical difficulties in Internet cafes. I have a ton more from Venezuela to upload, which I will so as soon as I get a decent Internet connection.

Popularity: 53%

Canaima, Roraima and Isla Margarita

I last posted about 11 days ago from Ciudad Bolívar the day before I left for Canaima and Roraima. When I arrived in Ciudad Bolívar I met a guy named Akira from Japan that also wanted to go to Canaima and Roraima. We left the next day for Canaima on a single engine Cessna with two Germans and an Austrian. It was about an hour-and-a-half flight to Canaima National Park and the low altitude flight gave a great view of the tepuis (flat-top mountains) and Canaima Lagoon as we approached the park. On the way there one of the German guys leaned against the door to take a photo and it popped open! The force of the air pushed the door back (mostly) closed, but it certainly made for an interesting flight. I spent three days and two nights in Canaima. Shortly after I arrived we took a boat up river to see Salto Angel, the tallest waterfall in the world. It was a four-hour journey up river to the falls and then a one hour hike through the rainforest up to the base. Ordinarily this journey is only possible during the summer months, which is the rainy season because during the dry season the river is too low and the falls are reduced to a trickle. Now, because of changes in climate, the falls are accessible most of the year. Still the river was not that high. Our boat had to crash through rapids and over rocks while going upstream, soaking everyone onboard. After viewing the falls and swimming underneath it we spent the night at a camp across the river sleeping outside in hammocks with mosquito nets. The next day we went back down river to explore the lagoon and some of the other falls.

After returning from Canaima to Ciudad Bolívar, Akira and I got on the night bus to Santa Elena de Uairén to find a guide for our trek up Roraima. Santa Elena is near the border of Venezuela, Brazil and Guyana. Roraima is flat-top mountain called a tepui by the local Pemón indians. Tepuis are found in Guyana, Brazil and Venezuela and were formed after South America and Africa separated a few billion years ago. They are supposed to be some of the oldest mountains in the world.

On the bus ride we met an American couple, Nico and Lejla, that were interested to doing the trek. After getting into town the four of us found a tour company to give a guide and hire us two porters, to lug our food. Our guide’s name was Tomás. He is a Pemón and really nice guy. He told us a lot about his culture and the tribal history and its legends. The next morning when were about to leave a Preuvian guy named Báulio joined us at the last moment. Báulio lives in Cuiabá, Brail and owns a company that gives bird watching tours in the Amazon and elsewhere. The man is passionate about birds!

The trail-head is about an hour and a half ride from Santa Elena in a Pemón village whose name I cannot recall right now. As we where leaving, a huge group of Brits (30+, I think) were just getting back. Apparently many of them didn’t make it to the top of Roraima, even though they were carrying anything. But what they did do was exhaust most of the porters in town so Tomás told us to start and he’d find porters and meet us later at the first camp site. The first site on the Río Tek and was a pretty easy walk. We got there just before sundown and set up our tents. But while some of the other groups there were eating dinner, Tomás and the porters were nowhere to be found. Another group on the way down was kind enough to give us some leftover food while we waited. After asking some of the other porters, that had walkie-talkies, we got mixed stories that he was either drunk back in town or on his way. He showed up around 10:30, having secured only one full-time porter and another for a couple of days. We finally ate a real dinner around 11:30 after most of the other groups went to bed.

The second day was probably the hardest. It was four and a half hours of nearly non-stop uphill hiking. We had two rivers to cross, which could only be done in socks since the water since the rocks in the river bed were too slippery to do in flip-flops or barefoot. We tried both again Tomás’ advice and nearly fell in river with all our gear on our backs. At one point Nico slipped, soaked his camera and lost one of his shoes, which he had been holding in his had. Lejla chased it downriver and grabbed it just before if went over a small cascade that would have sent it much further down river. By the time we reached Base Camp that afternoon my legs we throbing. We were now in the shadows of Roraima.

Roraima is in the La Gran Sabana and as the name suggests it is mostly a grassy savannah. But the mountain itself is skirted in a lush rainforest because the weather is much diffrent on top of the mountain. Roraima is almost always shrouded in cloud and receive a lot of rain all year round. Base Camp is where the savannah ends of the forest begins.

The next morning when we set out to the top the mountain, it was totally clear. There were no clouds. We all had a fingers crossed the it would last although we were told it was unlikley. All the groups we met on their way back told us that is was cold, cloudy and rained the whole time we were on top.

A few hundred feet outside of Base Camp we crossed a small river fed by one of Roraima many waterfalls. After that we began a steep acsent the required I use hands to help pull me up. That acsent lasted about and hour until we reached the wall of the mountain. After that it was a series of ups and downs until we reached the final steep acsent though a waterfall and over trail and smaller rocks that had fallen of the mountain. Nearly each step I took caused a small rock slide. Akira was behind me and made sure to keep a safe distance.

When we got the top all was still clear. It was a beautiful day. A few clouds blew through occasionally, but it was warm and gave a great opportunity to explore the mountain. Roraima and the Tepuis in general have many species of the endemic wild and plantlife. After a while Tomás took us the one of the “hotels” where we set up our tents. The hotels are like little caves where there is reasonable shelter from the wind and rain.

The next day, day four, we a little overcast but still warm and we spent the day exploring the mountain top. They call it a flat-top mountain, but it is anything but flat. The entire suface consist if rocky outcropings that have been carved out by billions of years of water and wind. Some are more than 100 feet high and they are all pretty much accessible to climbing. That night it rained from around 1AM until sunrise. By morning it cleared up.

Our decent on day five was all the back to the camp by the Río Tek. After four days my legs we pretty tired and the decents was tough because I barely had the leg strength to stop my momentum on the way down. By the time we got back to the village on the last day, my legs were shot.

We all went back to Santa Elena that afternoon, had a nice big dinner and slept. The next day (the 15th) Nico, Lejla and Akira all went to Brazil and I took an overnight bus to Puerto La Cruz where I am now waiting for the ferry to Margarita Island where I plan to spend my last few days in Venezuela in the sun.

See some photos on Flicker. I will try to put some more up soon.

Popularity: 39%