Pragmatic Programmer's iPhone SDK Screencasts - Some tips if you are trying to follow part I

Like a lot of developers, I was happy to see Apple lift the NDA for the iPhone SDK. I bought several of the items that Pragmatic Programmers released about the iPhone SDK. Here’s a few random tips I would like to share for anyone following the first screencast:

When making the connection between your View and File’s Owner, hold Ctrl while clicking and dragging

The way to prompt Xcode to help you out with some autocompletion is to hit Alt+Esc. This is useful at the point when he calls initWithFrame reuseIdentifier

If you are missing CoreGraphics.Framework from the list of installed Frameworks, search for CoreGraphics.Framework in Finder and make sure you select the one “iPhone Simulator” in the path. Add that to your project by clicking the Add Files button

I am by no means an expert on any of this, but these were a few of things that tripped me up along the way.

ArgumentError (wrong number of arguments (3 for 1): ActiveRecord::Base#attributes_with_quotes

While porting an application from Rails 1.2.3 to Rails 2.1, I encountered the error message in the title of this post. This particularly application has roots in pre-Rails 1.2.3 days, and the process of porting mainly consisted of simple things like removing calls to end_form_tag, modifying the call to form_tag to use a block, and finding the appropriate url generating method for nested resources. It was going smoothly, though a bit tedious, up until this point.

After examining the call stack, I noticed only one line was a reference to the application code. Surely the error was there, right? I checked the referenced line in my application and found the following:

   1  if @event.update_attributes(params[:event])
   2    ...
   3  end

At this point, I got a little concerned. I knew there was nothing wrong with the call to update_attributes. Then I remembered that the Rails 1.2.3 version of the application made use of acts_as_tree which was later extracted into a plugin (which I had to install during the process of porting). So the next logical step was to peruse the source of the acts_as_tree plugin. I didn’t find any crazy monkey patching going on in the plugin, which was simultaneously comforting and troubling. After searching the tubes a bit, I stumbled across this post. I thought to myself, “Hey, I remember that post. I remember telling former_colleague about that post when I found it.” It also happens former_colleague was the original developer of the application. But it still didn’t dawn on me at that point, so I just decided to check every location where ActiveRecord was being monkey patched (thankfully, there were not many). The first place I checked slapped me in the face—it was one of the patches demonstrated in the above post.

I removed the offending code, and walked away feeling a little more seasoned. While I have been doing Ruby on and off for awhile, that was the first time I had to debug an issue involving monkey patching.

Running the ultrasphinx rake tasks on the Production Server

The ultrasphinx plugin adds a number of handy rake tasks for use in development. But what about running them on the production server? In my first foray into custom Capistrano tasks, I arrived at the following code:

   1  namespace :ultrasphinx do
   2    [:bootstrap, :configure].each do |t|
   3      desc "run the ultrasphinx:#{t} rake task on the production server"
   4      task t, :roles => :app do
   5        run "cd #{current_path} && rake ultrasphinx:#{t} RAILS_ENV=production"
   6      end
   7    end
   8    
   9    namespace :daemon do
  10      [:restart, :start, :status, :stop].each do |t|
  11        desc "run the ultrasphinx:daemon:#{t} rake task on the production server"
  12        task t, :roles => :app do
  13          run "cd #{current_path} && rake ultrasphinx:daemon:#{t} RAILS_ENV=production"
  14        end
  15      end
  16    end
  17    
  18    [:delta, :main, :merge].each do |t|
  19      desc "run the ultrasphinx:index:#{t} rake task on the production server"
  20      task t, :roles => :app do
  21        run "cd #{current_path} && rake ultrasphinx:index:#{t} RAILS_ENV=production"
  22      end
  23    end
  24    
  25    desc "run the ultrasphinx:index rake task on the production server"
  26    task :index, :roles => :app do
  27      run "cd #{current_path} && rake ultrasphinx:index RAILS_ENV=production"
  28    end
  29    
  30    namespace :spelling do
  31      desc "run the ultrasphinx:spelling:build rake task on the production server"
  32      task :build, :roles => :app do
  33        run "cd #{current_path} && rake ultrasphix:spelling:build RAILS_ENV=production"
  34      end
  35    end
  36  end

You’ll want to take note of the subtle inconsistency your Capistrano tasks will have compared to your rake tasks. Specifically, the tasks under the `ultrasphinx:index` namespace will be accessible in the `ultrashinx` Capistrano namespace. This was due to `ultrasphinx:index` serving as both a task and a namespace in the rake tasks, and my lack of finding a way duplicate that with Capistrano. (Honestly, I didn’t try that hard. I am pretty satisfied with this solution.)

Hopefully someone will find this helpful for managing ultrasphinx in a production environment, although I guess this post also serves as a pretty basic example of writing custom Capistrano tasks.

Installing ultrasphinx (svn: URL 'svn://rubyforge.org/var/svn/fauna/ultrasphinx/trunk' doesn't exist)... a possible solution

While building this blog engine, I knew I wanted good search capabilities. I had heard good things about sphinx, so I decided to give it a try and see what was available for integration with Rails.

I tried getting started with this article. I quickly ran into problems with the installation instructions, in particular, this line:

   1  ruby script/plugin install svn://rubyforge.org/var/svn/fauna/ultrasphinx/trunk

The problem is that URL no longer works (or at least wasn’t working on 7/19/2008). The purpose of this post is to describe what I had to do to work around this issue.

Most of the posts I have seen on ultrasphinx strongly advocate installing it as a plugin, though I believe I found one that recommended installing it as a gem. Since the URL didn’t work, I had no choice but to install as a gem. The gem installation went fine. I used the following command:

   1  sudo gem install ultrasphinx

After a few hours of futzing around with making my Rails app load the gem correctly, I revisited the plugin idea. What ultimately worked for me was to copy some files from the gem installation into my plugins folder.

First, create the folder for the ultrasphinx plugin:

   1  mkdir vendor/plugins/ultrasphinx

Next, you need to find where your ultrasphinx gem was installed. My was located at /usr/local/lib/ruby/gems/1.8/gems/ultrasphinx-1.11/

Copy the necessary files from that location to the ultrasphinx folder you previously created.

   1  cp /usr/local/lib/ruby/gems/1.8/gems/ultrasphinx-1.11/init.rb path/to/your/project/vendor/plugins/ultrasphinx
   2  cp -r /usr/local/lib/ruby/gems/1.8/gems/ultrasphinx-1.11/lib path/to/your/project/vendor/plugins/ultrasphinx  

Your app now has the ultrasphinx plugin installed. I hope you found this helpful. Happy searching!

About

Jim BarnettI'm Jim Barnett, a software developer based in Dallas, TX. I began my career working for an FAA contractor building desktop applications in C++ for maintaining navigational aids (primarily ILS). In the summer of 2007, I decided to pursue a career in web development and joined Click Here, a full service interactive agency in Dallas, TX. My current work involves C#, reporting, and a very large (and rapidly growing) database.

In my spare time, I enjoy spending time with my wife, Adrienne, thinking about programming languages, avoiding manual labor, and watching sports.

Networking