posts by tag

ruby (33)
Rails plugin: EasySearch

Have you ever written a plugin or a piece of code that was more fun to write than it was actually worth? I seem to do that a lot—I enjoy experimenting with Ruby. Recently, I needed to search ActiveRecord models individually, and was in the mood to write a simple DSL. It’s now in plugin form, called EasySearch, and can be found on GitHub.

It doesn’t support joins or shared indexes or anything else you might come to expect from a search plugin. I’m posting about it not because I think you should use it, but because I think it’s a pretty cool API for searching.

So, install the plugin and do something like this:

class Search
  include RPH::EasySearch
end

(I originally had a nice acts_as_easy_search class method that hooked up the behavior, but I didn’t feel right about mixing that into Object. I wanted this plugin to work without the need of an ActiveRecord superclass. Plus, AR would then be expecting a corresponding table in the database, which is another unnecessary need. So, manual inclusion is the answer until I come to terms with a better alternative. Continuing…)

The Search class now has the means to easily search any ActiveRecord model within an application. Let’s say I want to find all of the users who mention ‘ruby’. Let’s reword that: search users with the term ‘ruby’.

$> Search.users.with('ruby')
$> # => [<#User ...>, <#User ...>, ...]

Makes sense, huh?

I have a confession to make: I lied about only having to include the module. Before anything will actually work, I’ll need to tell EasySearch about the tables I want to easily search.

EasySearch Configuration

For any generic search plugin to work, there needs to be a way to specify which database columns the search terms should be matched against. Here’s an example of how it works:

# in Rails 2.0+ you could put this in 
# config/initializers/easy_search_setup.rb
# (otherwise just use config/environment.rb)

RPH::EasySearch::Setup.config do
  setup_tables do
    users    :first_name, :last_name, :email, :bio
    projects :title, :description
    groups   :name
  end
end

There, that’s it (for real this time).

If you notice, it looks like there are “users”, “projects”, and “groups” methods that are called from within the block. And actually, that’s correct. The only difference is those methods don’t exist until they’re called, and even then they don’t “exist” (which is kind of weird, I know, but incredibly awesome nonetheless). Don’t worry about how it works (read through the code if you’re interested), just follow the pattern (use the table names instead of the model names).

After this one-time configuration is done, I can do things like:

$> Search.users.with('ryan')
$> # => [<#User ...>]
$> Search.projects.with('design')
$> # => [<#Project ...>]
$> Search.groups.with('friends')
$> # => [<#Group ...>]

If you try to search a model that hasn’t been configured, EasySearch will let you know. After all, how else would it know which columns to look in? It’s not that magical.

And getting a hold of the current table configuration is easy:

$> RPH::EasySearch::Setup.table_settings
$> # => {"users" => [:first_name, :last_name, :email, :bio], "projects" => ...}

How it Works

Really, all EasySearch is doing is building a WHERE clause and using conventions to pass that on to the appropriate finder. So Search.users is really doing User.find with a custom conditions clause.

Let’s say I want to search my User model for “ryan heath ruby”.

Search.users.with('ryan heath ruby')

This would not only compare “ryan heath ruby” with each of the specified columns (you know, from the configuration), but it’d compare “ryan”, “heath”, and “ruby” individually against each of the specified columns, providing more accurate results.

This, however, is an incredible performance limitation and is why this plugin is not meant for those gigantic applications with tons and tons of database records. It builds a potentially large WHERE clause using LIKE, which is quite slow in the computer world. For those large applications, it’s far better to use a full text solution. But again, this is all (more-or-less) for fun with little profit. I had a need to search individual models separately in a small application, so there you go. I can always go back and rework the back-end to operate differently/more efficient.

Oh, and since a rather large WHERE clause is being constructed, checking each term individually, I want to ignore meaningless words to avoid the extra overhead. For example, let’s say I tweak my search to be:

Search.users.with('ryan heath is a ruby')

EasySearch would still only search “ryan”, “heath”, and “ruby”, ignoring the “is” and “a” (because they’re dull). You can easily see what keywords are considered “dull” by doing:

$> RPH::EasySearch::Setup.dull_keywords
$> # => ['the', 'a', ...]

Now I know what you’re thinking, “Who gets to decide what keywords are dull keywords?” The programmer, of course! By default, EasySearch has a predefined list of keywords that it thinks are meaningless. But you can add to that list quite easily. Using the same Setup.config block:

RPH::EasySearch::Setup.config do
  setup_tables do
    # ...
  end

  strip_keywords do
    ['other', 'words', 'you', 'do', 'not', 'want', 'to', 'search']
  end
end

That will append those keywords to the default list (and will only count a dull keyword once, so don’t worry about duplication). If I wanted to ignore the default list completely (instead of appending to it), I’d just have to pass true to the strip_keywords method, like so:

strip_keywords(true) do
  ['other', 'words', 'you', 'do', 'not', 'want', 'to', 'search']
end

So that’s about it. It’s a fun plugin to play with, and like I said, it was more fun to write than it’s probably worth. But honestly, I think this sort of experimentation is nothing but good for programmer experience. And besides, every now and then, an “experiment” turns into something awesome (see Ambition for a prime example).

Ruby conditions

Often the conditions of an if statement are dependent on more than one thing, and sometimes it’s of the form, “if A is true and B is false”.

Avoiding the details, let’s say I wanted to do something like this:

user.cache! if user.needs_cached? && !API.local?

Essentially that’s saying “cache the user if the user needs cached (A is true) and the API is NOT a local request (B is false). The && ! is fine and all, and it’s actually quite readable to most programmers, but were you aware that you could do this?

user.cache! if user.needs_cached? unless API.local?

Maybe I’m flying solo on this one, but I wasn’t aware that you could use if and unless to chain conditions together. And I’m sure this is one of those Ruby moments where I just need to take a step back and find the right perspective. Sometimes things aren’t always what they seem (like how 1+3 is actually 1.+(3)).

Testing block helpers with Rspec

One of the many great things about Rspec is that it allows you to test helper methods. Helpers can be complex at times. And when it matters, they definitely need some testing love.

An example of a typical helper may be something like:

def h1(text)
  "<h1 class='heading'>#{text}</h1>"
end

Then you can do <%=h1 'Text Here' -%> in your views. That’s trivial to test, so I won’t go into that. The tricky tests (I think) deal with block helpers. Block helpers are extremely useful and can improve the readability of what’s going on in your view(s). Probably the most useful case is when you have <% if current_user.admin? %> scattered all over the place. Wouldn’t it be better (and DRYer) to wrap that “admin condition” up in one place?

def content_for_admin(&block)
  yield if current_user.admin?
end

Pretty simple. But, how would you test that? Initially, I had somewhat of a hard time writing tests to see if the block was actually yielded or not. Here’s what I do now, but I’m open to (and seeking more) alternatives. Using the content_for_admin helper as the guinea pig:

describe ApplicationHelper do
  attr_accessor :_erbout
  fixtures :users

  before(:each) do
    self._erbout = ''
    @block = "This is the block content"
    @current_user = users(:admin)
  end

  # current_user.admin? # => true
  it "should yield block for an admin" do
    should_receive(:current_user).and_return(@current_user)
    @current_user.should_receive(:admin?).and_return(true)

    html = content_for_admin do
      self._erbout << "<div>#{@block}</div>"
    end
    html.should have_tag('div', @block)
  end

  # current_user.admin? # => false
  it "should not yield block for a non-admin" do
    should_receive(:current_user).and_return(@current_user)
    @current_user.should_receive(:admin?).and_return(false)

    html = content_for_admin do
      self._erbout << "<div>#{@block}</div>"
    end
    html.should_not have_tag('div', @block)
  end
end

Another, similar, approach is to use eval_erb, which let’s you actually write out the ERB as a string (or heredoc) and evaluate the output. I think that’s a little messy, but then again, I’ve never actually tried it.

But other than that, this is the only way I know to test the yielded output of a block helper with Rspec. Do you know of a better way? Or at least, a different way?

Afraid of Ruby 1.9

Ignore this post. I bit on an April fools joke that I read on April 6th. Way to pay attention. Anyway, the only valid point here is related to send, but that’s hardly a big deal.

I’ve come to absolutely love Ruby. I just love the syntax. But lately I’ve been reading a bit about Ruby 1.9, and it makes me a little worried about Ruby’s (and Rails’) future.

Here are a few of the methods being removed in Ruby 1.9:

  • method_missing—Yep, that’s right. No more method_missing. This is disastrous for Rails, as well as a good chunk of meta-programming practices. The argument is the same as it always is, too much abuse. But the dynamism of things like method_missing is what makes Ruby so exciting (and challenging), IMHO.
  • const_missing—Maybe not quite as important, but const_missing is getting removed for the same reason: too much abuse. I’ll admit, I’ve not used this one too much, but I’ve read about a few clever ways people are using it (unicode-based character escapes, for example).
  • send—And finally, send will no longer be available in Ruby 1.9. While there are more important things to worry about (see both bullets above), this is still something to deal with. I’m using send all over the place in all of my projects. The AR::Base.send(:include, RPH::Module) pattern is a commonality that can be found in most plugins. I believe there’s a drop-in replacement for send (I can’t remember what it is), so a quick fix would be to create an alias method (send) for the newly named version.

They say it takes 10 years or so to learn a programming language. Applying that logic to Ruby, I’m only 20% of the way there. So maybe these changes won’t hurt Ruby. Maybe they’ll be better for the language. I don’t really know. I’m a far cry from a language designer. But man, I’m having a rough time finding the positive with getting rid of method_missing and const_missing. Only time will tell, I suppose.

Maybe it’s time to see what advances PHP has made? Just kidding. Ruby had me at “Hello World”.

Writing Readable Code

Writing code in Ruby is a real pleasure. It’s a very expressive language, and that allows me to make complex programming problems read like English.

For instance, at work recently I needed to authenticate against a separate system (written in .NET). I also needed to cache the user to the application’s DB for speed and convenience. And I also needed to make sure the cached version gets updated if the .NET version gets updated. Etc. Etc. Etc. The point is there was a lot to do there, but it didn’t have to appear that way.

User.process_login(username, password)

Once that complicated mess is abstracted, that’s all I have to do. Here’s a piece of the mixed in module that does a little more of the dirty work:

def process_login(username, password)
  returning Proxy.authenticate(username, password) do |user|
    cache! user if user && user.needs_cached?
  end
end

Proxy is a class that nicely handles the WSDL/SOAP communication to the .NET system; the authenticate method on the Proxy authenticates against the .NET system’s DB; the cache! method (you guessed it) does the caching based on a last-modified date comparison of the returned SOAP user versus the cached version (if there even is one). The returning part simply returns the user object or nil, depending on if the authentication was successful or not.

Hopefully you’re thinking, “there was really no need to explain all of that.” Because the goal here isn’t to focus on all of the behind-the-scenes mumbo-jumbo, it’s to give yet another example of how clearly a complex thing can be written in Ruby.

I might even be able to show that to my Mom and have her tell me what it’s doing. Well, maybe not, but the average (technically-minded) person would have no problem.

As an aside, this is what I’m really starting to love about Rspec. It sort of guides your mind into writing readable code, which I’m all about.

Consuming SOAP services in Ruby

I know, I know, REST is cool and SOAP sucks. Rails is awesome and .NET blows. But the reality is I have to do a little bit of both.

Things at work are moving more and more toward Rails, but there’s still a large investment in a few .NET systems that must be maintained (until the decision is made to rewrite them in Rails). With that means there are a few SOAP services that I still need to work with. It turns out, this isn’t so bad.

Originally I thought I’d bring back AWS and deal with it that way. But from my experience, AWS has more support for generating services rather than consuming services. While AWS isn’t a terrible approach, there’s an easier way this can be handled: SOAP::WSDLDriverFactory. This is a straight-up Ruby solution that comes shipped with the standard library. It’s straight-forward to use and requires no XML parsing (which sort of surprised me).

As an example, one of the Rails applications I’m currently working on needed to have the ability perform certain actions under that users’ .NET account. Mainly, since the applications are completely separate (read: separate DB, separate users table), I needed to get the user id from the .NET system via their credentials in the Rails system. While this isn’t the actual implementation, you can see how easy this is to do.

require 'soap/wsdlDriver'

class SomeDotNetWrapper
  attr_accesssor :endpoint, :service

  def initialize(endpoint=nil, service=nil)
    @endpoint = endpoint
    @service  = service
  end

  def get_user_id_from_credentials(username, password)
    soap = wsdl.create_rpc_driver
    response = soap.GetUserID(:username => username, :password => password)
    soap.reset_stream
    response.getUserIDResult
  end

  private
    def wsdl
      SOAP::WSDLDriverFactory.new("http://#{@endpoint}/services/#{@service}.asmx?WSDL"
    end
end

By creating a “factory” with the services’ WSDL, you can easily set things up for remote procedure calls (i.e. GetUserID(username, password)). What’s even nicer is that you can parse the response by chaining methods together. In this case, it put me right inside the response, where I only needed to call one level of nested XML (response.getUserIDResult). But if this were nested deeper, I’d just keep calling the methods that map to the XML nodes until I got to what I wanted. And of course, I could then write any Ruby code to do what I needed to do, but the point is it’s automatically method-like access, which is nice (think of Builder).

So, once you write your “wrapper” class, you’re ready to go.

class SomeDotNetWrapperController < ApplicationController

  def store_other_id
    raise InvalidCredentials if params[:username].blank? || params[:password].blank?
    service = SomeDotNetWrapper.new('http://example.com', 'authentication')
    other_id = service.get_user_id_from_credentials(params[:username], params[:password])
    current_user.update_attribute(:other_id, other_id) unless other_id.to_i == 0
  rescue InvalidCredentials
    # ...
  end
end

I’m sure there are a lot of different approaches, but this seemed the easiest to me. I had somewhat of a difficult time finding a solid solution online for easily consuming .NET SOAP services, so I decided to resort back to the standard library, as generally every language has support for this sort of thing. Anyway, maybe someone else with the same needs will find this useful.

A couple of additions to Ruby Hash

Ruby is near perfect in and of itself, and it’s sometimes hard to fathom how Rails improves upon that perfectness. But there are still times when a little extra is needed. Luckily, that’s not a problem. Here are a couple of methods I’ve added to Hash that I use a good bit.

class Hash
  # names = {
  #   :first  => 'ryan',
  #   :middle => 'paul',
  #   :last   => 'heath'
  # }
  #
  # names.has_keys? :first, :last
  # => true
  # names.has_keys? :first, :title
  # => false
  def has_keys?(*keys)
    keys.each do |key|
      return false unless has_key?(key)
    end
    return true
  end

  # names.pairs :first, :last
  # => {:first => 'ryan', :last => 'heath'}
  # names.pairs :middle
  # => {:middle => 'paul'}
  def pairs(*keys)
    keys.inject({}) { |h,k| h[k] = self[k]; h }
  end
end

They’re simple extensions, but I find them to be quite useful. And I wouldn’t be surprised if Rails (or Ruby for that matter) already have something similar, but I couldn’t find them if so.

Upgraded syntax highlighting

I’ve been wanting to upgrade the syntax highlighting on this site for some time now. It’s perfect for Ruby, but it lacks support for other languages. Particularly, though, Rails’ view code looks horrible. It parses everything between the slashes, <td/>...</tr> for example, as a regex.

the solution

Enter Ultraviolet. To quote the site, “it is able to produce html output for all the syntaxes in Textmate’s repository.” Which is a ton. It also supports themes, line numbers, and has xhtml output. Here are a couple of examples…

# xhtml output for Ruby on Rails, 
# with line numbers, using the blackboard theme:
html = Uv.parse(text, "xhtml", "ruby_on_rails", true, "blackboard")

# xhtml output for ERB (view) templates in Rails, 
# without line numbers, using the sunburst theme:
html = Uv.parse(text, "xhtml", "html_rails", false, "sunburst")

It’s pretty cool. Chris was kind enough to show his implementation for syntax highlighting, but I needed to make a minor modification to the regexp to support code.[language] instead of only code.ruby. Here’s the Ultraviolet version:

require 'uv'

def colorize_code
  r = RedCloth.new(self[:body] || '')
  self[:body_html] = r.gsub(/<code.(\w+)>\s(.*?)<\/code.\1>/m) do
    lang, code = $1, $2
    html = "<notextile>" + Uv.parse(code, "xhtml", lang, true, "sunburst") + "</notextile>"
  end.to_html
end

I enjoy the line numbers, but by default they’re included with each line of code—to copy and paste means to remove each line number. If you care about that, here’s a way to create your own line numbers so that the code and line numbers are separated.

require 'uv'

def colorize_code
  r = RedCloth.new(self[:body] || '')
  self[:body_html] = r.gsub(/<code.(\w+)>\s(.*?)<\/code.\1>/m) do
    lang, code = $1, $2
    html   =  Uv.parse(code, "xhtml", lang, false, "sunburst")
    result =  "<notextile><pre class=\"lines\">"
    result << (1..code.split("\n").size).to_a.join("\n")
    result << "</pre>#{ html }</notextile>"
  end.to_html
end

Then just do a float:left; on the .lines CSS class, and viola, your line numbers are separate from your code. There’s one more thing to make note of, though. As horrible as this sounds, you may want to use an inline style on the pre tag in place of the CSS class. The reason is because of how the code will look when it goes out to an RSS reader. What it’s doing is putting an extra pre block with just the line numbers above your code, but the CSS makes it appear beside it. Personally, I found style="float:left;padding-left:10px;" to work well.

ultraviolet in production

So the implementation is pretty easy, but here’s where things get difficult and very annoying. This is also why I’m not currently using Ultraviolet (in production) yet. You see, Ultraviolet indirectly requires the use of the (what is supposed to incredible) Oniguruma regular expression library, which isn’t packaged with Ruby until Ruby 1.9 (but is available as a gem).

I installed the gem without any problems on my machine; however, I could not for the life of me get it working on DreamHost. I freeze my gems, but the problem is that it had to be installed and frozen from the server and not my local machine. Since I’m on Windows (blah) in development, the oregexp.c file was compiled for an mswin32 environment, which is not the case in production. Apparently that matters. I have very little experience modifying environment variables and .bash_profile and all the other jazz I found online, so I was a little timid to go further than I’d be able to fix.

unfortunate conclusions

After a couple (or few?) hours of hacking at things I didn’t really know how to hack, I ended up back at the beginning: using the plain old syntax gem. What a great feeling it is to waste hours of my personal time.

I considered extending the syntax library to satisfy me for the time being (mainly for view templates), but I haven’t decided yet if I want to get into that or not. But definitely not today. I’m burnt out on syntax highlighting.

In the end, Ultraviolet is an awesome syntax highlighting library, and you should think about using it. Unfortunately for me, I was unable to get it working on DreamHost thanks to Oniguruma, but maybe (if you actually know what you’re doing) it’ll go better for you. Good luck!

Ruby inheritance quiz

If you’re interested, here’s a quick Ruby inheritance quiz.

For some, I think the point of confusion would relate to the metaclass. This is how I understand it to work: it inserts a “virtual” class between the object and its real class, which makes the original class the superclass (or parent?), and the metaclass becomes the objects’ direct class for that instance. So the identify method hits the metaclass first because it was inserted (or attached to the object) after the object was created, and squeezed in before the Child class in the hierarchy. That’s why it [the metaclass] is able to intercept the call. I think, anyway.

Ruby is slick, readable, and fun to program, but it can be quite complex at times. If you didn’t get the “quiz” correct, stop now and learn why it works that way—it will save you troubleshooting time and make you a better Ruby programmer altogether.

How to use method_missing

There’s no doubt, Ruby can be tricky at times. But understanding it well (and not that I do) can greatly increase productivity, efficiency, and happiness. Seriously.

Would you believe me if I said I could randomly call Model.ryan_heath and dynamically teach Ruby that ryan_heath is a real method under the Model class? No, Ruby doesn’t come pre-packaged with a method that just-so-happens to be my name. There’d be no trick in that. Rather, this works because of method_missing. If you’ve never heard of method_missing, it’s simply a method that gets invoked after Ruby searches the entire class hierarchy for a method that doesn’t exist (Model.ryan_heath would result in Object.method_missing). So what, right? Wrong. Since methods can be easily overridden in Ruby, you can use this little hook to really help you write (or not write) code.

As an example (albeit, a shallow one) to show how flat out awesome this technique is, I’m going to use a snippet from Golf Trac (which is taking me forever to finish, by the way). So, in my golf application I have the obvious association that “a course has many holes”. Since I’ll be referencing those holes a good bit throughout the application, it would be nice to have a convenient way to access them. I’ll rarely (if at all) be asking for hole information outside the context of a course, and so it’d be best to define a method directly on the course-to-holes association.

While this can simply be any method I’d like, I chose to override method_missing (you’ll see my original intention in a minute). Here’s the top of my Course model:

class Course < ActiveRecord::Base
  has_many :rounds, :include => :scores
  has_many :holes do
    def method_missing(method)
      find(
        :first, 
        :conditions => { :hole_number => method.to_s.send(:gsub, /[a-z|A-Z|_]/, "").to_i }
      )
    end
  end
  ...
end

Here, find will always be scoped to a specific course, so I only need to worry about getting the appropriate hole. Now, to access the holes:

@course.holes.hole_10
# => tenth hole
@course.holes.hole_18
# => eighteenth hole

The best part is, the hole_10 and hole_18 methods don’t really exist! How cool is that?

Also, looping through all of the holes using the above implementation may seem to make sense, but it doesn’t. If I were to use the above jargon, I’d be doing a separate query for each hole in the loop. In that case, I’d probably rather eager load the holes instead. However, if I didn’t care to run 18 separate queries, it could be done like so:

(1..18).each do |i|
  puts "Par for the #{i.ordinalize} hole is #{@course.holes.send("hole_#{i}".to_sym).par}."
end

## results
 # => "Par for the 1st hole is 4."
 # => "Par for the 2nd hole is 3."
 # => ...

I’ve essentially told Ruby that there are 18 methods (hole_1, hole_2, ...hole_18) defined on the course-to-holes association, when really there’s nothing more than a single method_missing hook. That’s just awesome to me.

And now it’s time for my original intention. Originally, I had planned on using the hole number itself as the method, which would have been easier and much cleaner. But I can’t seem to get it to work. I’m currently using course.holes._10 instead of the more redundant, course.holes.hole_10, but what I really want is just course.holes.10.

def method_missing(method)
  find(:first, :conditions => { :hole_number => method.to_i })
end

@course.holes.18
# => eighteenth hole
@course.holes.11
# => eleventh hole

But, and correct me if I’m wrong, it’s apparent that Ruby doesn’t quite understand integers as method calls. Oh well, Ruby does so many things that amaze me, it was worth a shot. If anyone has a thought or two as to how I can get course.holes.18 to return the 18th hole, I’d love to hear them.

I still have a lot, a lot, to learn about metaprogramming, but it definitely feels good to have your code do extra work for you. If you have a clever method_missing example, feel free to leave it in the comments.

Raising custom exceptions in Rails

I’ve grown to not like the if/else block at all. Here’s an example of what I’m not fond of:

def do_some_work
  unless feeling_lazy?
    if current_user.is_boss
      do_boss_work
    else
      do_work
    end
    flash[:notice] = "Glad you're working hard."
  else
    redirect_to lazy_page_path
    flash[:error] = "You're too lazy to work here."
  end
end

The if/else statements just clutter the code. It disguises the logic by its ugliness. When appropriate, I’ll avoid if/else by raising exceptions to handle the “else” condition. That way, I can assume everything works how I want it to, and just raise if it doesn’t. Something like this is much better, in my opinion…

def do_some_work
  raise if feeling_lazy?
  current_user.is_boss ? do_boss_work : do_work
  flash[:notice] = "Glad you're working hard."
rescue
  redirect_to lazy_page_path
  flash[:error] = "You're too lazy to work here."
end

That’s much easier on the eyes. But I like to raise application-specific exceptions instead of the generic “rescue everything” solution. The way I’m currently doing this feels a little, I don’t know, sloppy. What I usually do is put a separate module in the lib folder, then include it in ApplicationController so it’s available everywhere. Something like this:

# lib/exceptions.rb
module Exceptions
  class TooLazyToWork < StandardError; end
  class NotTheBoss < StandardError; end
end

# using the custom exceptions
def do_some_work
  raise Exceptions::TooLazyToWork if feeling_lazy?
  ...
rescue Exceptions::TooLazyToWork => exception
  flash[:error] = "You can't work: #{exception.message}"
end

I’m not doing anything with the class except inheriting from StandardError (or Error, RunTimeError, etc)—that’s what feels sloppy. Is there a better way to achieve this? If you notice something that could be (or should be) done better (or differently), I’d appreciate the advice.

Code abstraction and Rails

Sometimes I have a hard time abstracting code when developing in Rails. I mean, the act of abstraction itself isn’t the problem, it’s how far to go with it—or more accurately, when to stop.

When I first started doing web development, I wasn’t too concerned with abstraction. I barely even knew what it was. Like most beginners, if I got something to work, I was satisfied… until I wanted to update something. It was an obvious pain to modify and update code, since I had to remember (or search) for all instances to stay consistent. Then (in addition to object-orientation), I realized that anything I was duplicating I should extract out so I could reuse it—brilliant! (It’s weird to think I was at a point where I didn’t think like that.) So I began to abstract only to prevent duplication. Now, with Rails, I can’t help but abstract everything. Ruby is so readable by nature, it’s stupidly tempting to want to continue that.

I enjoy immediately knowing what’s going on in any of my methods, just by reading them. Typically, I set them up that way. Sometimes, though, it seems like I’m tracing through all of these abstracted methods, and I don’t know if that’s a good thing. As an example, here’s a method I wrote to publish content out to XML:

def publish_xml_for(root_id)
  content = Content.find(root_id)
  create_publish_directory_for(content)
  output_xml_for(content)
  flag_as_published(content)
end

Anyone can look at that and know what’s going on. I’m not necessarily reusing any of those methods (yet, anyway), I just like how readable it is. But altogether, the publish_xml_for method works as a compilation of 5 or 6 methods (the methods inside of it are also abstracted to be very readable—it never ends).

Also, I find myself writing private methods within the controller class—would it be better to add these to some sort of extension in the lib directory? I don’t do that very often, so I have yet to build up habits as to when that should happen. I’ve written some tag extensions for polymorphic tagging, but that’s about it.

Meta-programming and the singleton class

Confusing, confusing, confusing. I finally have the opportunity to play with the has_many_polymorphs plugin. I’m using it to handle tagging. As suggested, I’ve written several tag extensions (tag_with, tag_list, tagged_with?, etc). I’m not having trouble writing methods that work on an instance of a class, it’s when I want to add methods that work directly on a class itself (even though a class is an instance of the class, Class—right?). I’ve read a couple of articles, but man, this stuff is tricky.

What I wanted to do was give each model a class method such as find_tagged_with. I thought it would be cleaner as a class method of the “taggable” class in question (but without me having to explicitly define it in each class, as that would defeat the purpose), rather than always referring back to the Tag class. This is how it works currently:

class Dog < ActiveRecord::Base; end;
class Cat < ActiveRecord::Base; end;

Tag.find_by_name("animals").dogs
# => {all dogs tagged with "animals"}

Tag.find_by_name("animals").cats
# => {all cats tagged with "animals"}

I could leave it as is, but it’s not as intuitive as I’d like it to be. Since I’m getting objects of the Dog and Cat classes independently, I would like to have the find_tagged_with method become part of those classes. So I could do something like:

Dog.find_tagged_with "animals"
Cat.find_tagged_with "animals"

From what I’ve read, class methods are just singleton methods defined on the instance of the class in question. So they wouldn’t apply to all instances of a class, but I wouldn’t need them to. I figured I would need to open up the singleton class, since that would only apply to one object. The “taggable” class would be the object, since they are really just instances of the class, Class (and all objects have singleton methods). But obviously what I was thinking wasn’t right, since all I can come up with is “undefined method ‘find_tagged_with’ for ”. I don’t know, maybe I should just move to the mountains and study the Ruby language night and day, since I keep finding more and more I don’t understand.

How to automate tasks using Ruby or Rails?

I’ve yet to get the cron job to consistently execute for the flickr and delicious caching. I’ve tried several different things, but nothing seems to work. So I’ve started seeking alternatives. There are three different methods listed, but it’s not obvious to me how they might work. If I were to setup a scheduler, would I then “start” it when Rails initializes in environment.rb? Of all three options, I’m at a loss as to which one I should pursue.

Right now I’m calling refresh_api_cache via a “refresh” link that appears upon login:

def refresh_api_cache
  reload_cache(ENV['RAILS_ENV']) and redirect_to :back
end

private

def reload_cache(env)
  command = "ruby #{RAILS_ROOT}/script/custom/api_cache.rb"
  env =~ /development|test/ ? system command : exec command
end

That’s not terribly inconvenient, but it requires two things to happen (tag something in delicious or flickr and then come here and click “refresh”). I want this to be automated. Any tips on scheduling in Ruby/Rails?

RSS aggregator in 26 lines of Ruby

Ruby is awesome, but we already knew that. Leveraging the libraries in Ruby can be well worth the effort. Here’s a case where four Ruby gems were used to write a simple RSS aggregator, in 26 lines of code mind you:

Pretty impressive, I think.

Navigation helper acting weird

The I’ve handled tabs in the past has always bothered me. I’m trying to handle them a different way, now that I have better options. Just like anything you do the first time, I’m sure this could be improved upon—but here’s what I have:

# application_helper.rb
def main_navigation(links)
  li_class, link_class = 'left', 'non-current'
  nav_bar = Array.new
  links.each do |link|
    li_class = 'right' if controller.controller_name.downcase == 'settings'
    link_class = 'current' if controller.controller_name.downcase == link.downcase
    nav_bar << "<li class='#{li_class}'>#{link_to link.capitalize, '/' + link.downcase, :class => link_class}</li>"
  end
  nav_bar
end

I’m calling this helper like this:

# layout
<%= main_navigation ['dashboard','messages','settings'] %>

Yes, each link does correspond to a controller, and the reason I’m changing the ‘settings’ tab is because I want it off to the right, separated from the other tabs. The concept is obvious, but this thing is acting crazy. Here’s what happens when I click…

  1. Dashboard—All three list items have class='left' and each tab has class='current'
  2. Messages—All three list items have class='left' but this time, the Dashboard tab has class='non-current'
  3. Settings—All three list items have class='right', and only the Settings tab has class='current' (which actually is the current section, making it the only one to follow the ‘current’ rule)

It seems like the li_class always applies to all three tabs, but the link_class doesn’t. Is there something blatantly wrong with this?

UPDATE—the only trouble I’m having is with the ‘left’ and ‘right’ settings. All tabs are left if I click on Dashboard or Messages, and all tabs are right if I click on Settings. I had the li_class and link_class being initialized outside the loop, like an ignoramus. But I can’t seem to get the settings tab to be the only tab with class='right'.

Programming in Ruby is like writing

Mark Twain once received a telegram from a publisher that read:

NEED 2-PAGE SHORT STORY 2 DAYS.

Twain replied:

NO CAN DO 2 PAGES 2 DAYS. CAN DO 30 PAGES 2 DAYS. NEED 30 DAYS TO DO 2 PAGES.

As his reply implicitly states, there are difficulties associated with short and concise writing—it’s not easy. I agree wholeheartedly. I think this same type of reality exists while programming in Ruby. I can get something working really fast, but (for me at least), it seems like I keep wanting to extract and refactor until the method is as small as it can possibly be. I could probably spend days trying to out-do my current code and get just as much satisfaction as if I were developing something new. I love how much you can do with one single line in Ruby. It’s motivational.

And for the record, I don’t apply the short and concise writing methodology here (obviously). This site just isn’t that sophisticated. But I can see the challenges and fun in that, too.

Rails tips and tricks, part 2

I’ve spent a few more minutes gathering up some more of what I learned at the Rails Edge conference, and here’s what I came up with for the second dose of tips and tricks in Rails.

Using returning

returning allows you to do some processing inside of a block of what you intend to return. And it will return the final state (so you can still modify it within the block). For instance, have you ever had code similar to this?

def get_vehicle_report(vehicle_id)
  vehicle = Vehicle.find(vehicle_id)
  report  = Report.new(vehicle_id, vehicle.year, vehicle.description)
  if report.something.nil?
    owner = vehicle.owner
    # ...
  end
  report
end

While it’s nice that Ruby will return the last executed line, saving you an extra word (return), there’s still a better way. Using returning, the method becomes:

def get_vehicle_report(vehicle_id)
  vehicle = Vehicle.find(vehicle_id)
  returning Report.new(vehicle_id, vehicle.year, vehicle.description) do |report|
    if report.something.nil?
      owner = vehicle.owner
      # ...
    end
  end
end

Not overly useful, but I personally think this is a cleaner way to handle the explicit return. And sorry for the poor excuse for a method, but you get the idea.

Using built-in Formatted Dates and Times

I was aware of this prior to the conference, but I’ll post it anyway. Did you know there are a few built-in options to get rid of strftime when formatting a datetime?

>> now = Time.now
>> now.to_s
#   => "Mon Mar 05 18:30:48 2007"
>> now.to_s(:db)
#   => "2007-03-05 18:30:48"
>> now.to_s(:short)
#   => "05 Mar 18:30"
>> now.to_s(:long)
#   => "March 05, 2007 18:30"
>> now.to_s(:rfc822)
#   => "Mon, 05 Mar 2007 18:30:48 -0600"

I’ve found the :db parameter to be particularly useful when writing fixtures, as it will be formatted to whatever database you happen to be using.

Formatting your own Dates and Times

But what if you don’t like the built-in options? Now this is really useful, and I was not aware of this prior to the conference.

# environment.rb
ActiveSupport::CoreExtenstions::Time::Conversions::DATE_FORMATS.merge!(
  :simple     => "%d %b %Y",
  :last_login => "Last login: %m/%d/%y at %I:%M %p"
)

# used the same as above
>> now.to_s(:simple)
#   => "05 Mar 2007"
>> now.to_s(:last_login)
#   => "Last login: 03/05/07 at 06:30 PM"

This is a much easier way to change-up your date formats all across your application. Oh yeah, something else I’ve learned that might be useful:

>> (now..then).to_s(:db)
#   => "BETWEEN '2007-03-05 18:30:48' AND '2007-03-06 08:00:00'"

Enumerable extensions

There’s not really a need for explanation, so I’ll just list a few examples:

## group_by
#  - Partition a collection based on the value returned by a block
>> (1..20).group_by {|n| n%3}
#   => {0=>[3,6,9,12,15,18],
#       1=>[1,4,7,10,13,16,19],
#       2=>[2,5,8,11,14,17,20]}

## index_by
#  - Convert a collection into a hash where keys are values returned by a block
>> (1..5).index_by {|n| n*10}
#   => {50=>5, 40=>4, 30=>3, 20=>2, 10=>1}

## sum
#  - Sum the values returned by the block
>> [1,3,5,7,9].sum
#   => 25
>> [1,3,5,7,9].sum {|n| n*n}
#   => 165
>> Orders.find(:all).sum {|o| o.total}
#   => 12345.67

Array extensions

I used to despise dealing with arrays, but now I’ve learned to embrace them and all they can do. Here are a few examples you should be aware of:

## in_groups_of
#  - Partitions an array into chunks of N elements
>> %w{ a b c d e f g h i j }.in_groups_of(3)
#   => [["a", "b", "c"],
#       ["d", "e", "f"],
#       ["g", "h", "i"],
#       ["j", nil, nil]]

## to_sentence
#  - Like #join on steroids (sometimes useful for listing tags)
>> names = %w{ Ryan Paul Heath }
>> names.to_sentence
#   => "Ryan, Paul, and Heath"
>> names.to_sentence(:connector => "and also")
#   => "Ryan, Paul, and also Heath"

Arrays have now become something I look forward to using. It’s fun to manipulate them using the least amount of code possible.

Another nice thing you should know (and I’m sure you already do) is the ability to do math-like operations on arrays—and they do not have to be numerical.

>> bowl_o_fruit  = %w{ apples oranges pears grapes bananas papaya }
>> plate_o_fruit = %w{ bananas pineapples papaya peaches oranges }

## How many fruits are in the bowl and not on the plate?
>> bowl_o_fruit - plate_o_fruit
#   => ["apples", "pears", "grapes"]

## What are the common fruits?
>> bowl_o_fruit && plate_o_fruit
#   => ["oranges", "bananas", "papaya"]

As a real example, at work I’m inserting tree-structured content from the file system into the database (activating it). So naturally I have to compare what’s in the database versus what’s in the file system (Read: get a ‘set difference’ of the files in the database and the directory). Here’s what I’m doing:

def view_published
  is_administrator(SUPER_ADMIN)
  directory_courses = read_directory
  active_courses, @activated_courses = [], []
  Course.list_active_courses.each do |ac|
    active_courses << ac.folder_title
    @activated_courses << ac
  end
  @available_courses = directory_courses - active_courses
end

Then I’m able to use the available_courses and activated_courses in the view. That may not be the best way to do it, but it’s far better than anything in C/C++ or something with similar syntax (i.e., Java).

I guess this is long enough now. Hopefully there were a few goodies in there, and if nothing else, you were reminded of something you’ve once read, but forgot to use. Feel free to add any related tips and tricks in the comments, as I often check back to posts like this for reference.

A wise man once asked me...

...So you aren’t caching the API data? Hanging my head, I had to answer with a No. But I decided to look into that option, as it would remove the direct coupling of my site and the APIs, speeding things up a bit in the process. While you may or may not have noticed, the main page has been an arbitrary hit-or-miss the last couple of weeks. Sometimes it’s up, taking it’s normal 4-5 seconds to load, and other times (when the delicious response data is randomly empty) it would either hang or instantly die (hence, the direct coupling).

Yesterday after church, I finally sat down to work out the kinks. I was fed up with the slow loading and down time. Using the suggestions Chris proposed, I was able to get things going. I’ve never used the Marshal library before, so I didn’t know what to expect; but it turned out to be extremely straightforward. I also wanted to use pure Ruby (no Rails) in my script, so I had to tweak it a little.

I exported the inner-workings of the original methods that grabbed the flickr and delicious data, and put that processing in a Ruby script located in my script folder. As expected, a few things were no longer accessible, including the to_date method. I just used the Ruby libraries directly (such as Date.parse in place of to_date to convert the ISO 8601 format). And all was well.

So the script processes the API data and Marshal.dump’s it to the file system. Those previous methods now simply look for the cached file and Marshal.load it back in, rather than dealing with the API responses directly. Not only do I like this solution a lot more, I’ve cut the load time of the main page from 4-5 seconds down to < 1 second (checked against one of those web page analyzers).

So the core of all of this is working; however, I do still have a problem: automating the script to run on a 30 minute schedule. I have a cron job for this, but apparently it isn’t working. Here’s the cron:

*/30 * * * * /usr/bin/ruby ~/rpheath.com/site/script/api_cache.rb >/dev/null 2>&1

The job is listed there when I check with crontab -l, but I don’t think it’s doing anything. Once I figure that out, I’ll be good to go. Oh, and thanks to Chris for the idea.

Rails tips and tricks, part 1

I picked up a few tips and tricks from the Rails Edge conference. Some of them I’ve seen before, but the discussions around them really helped me to see their value. I realize there are those who already know everything (ahem, Chris), but I’ll post all that I can remember, even if I think it’s fairly common.

Using with_scope

with_scope allows you to bind a block of code operating on an active record model to a particular subset of that model’s collection. Make sense? From words, it’s hard to see how this benefits you; but an example might clear things up a bit.

I’m often working in systems that involve users, and I always find myself passing the user_id around, which clutters and duplicates my code. For instance, here’s a case where I want to find a users ‘books’ and create a new ‘book’ for this uers. The old way:

user_id = current_user.id

# Getting the books for the current user
@user_books = Book.find(:all, :conditions => ["user_id = ?", user_id])

# Creating a new book for the current user
@book = Book.create(:title => params[:title], :user_id => user_id)

Wouldn’t it be nice to get that user_id stuff out of there? Let’s try the same thing using with_scope:

Book.with_scope(:find => {:conditions => "user_id = #{current_user.id}"},
                :create => {:user_id => current_user.id}) do

  # Find all user's books
  @user_books = Book.find(:all)

  # Create a new book without specifying user_id
  @book = Book.create(:title => params[:title])

end

In that example, I didn’t have to clutter up my core operations with excessive parameters, because I was working within scope of the current user. Very handy. And not only does this prevent redundant and messy code, but it can sort of allow you to take extra precaution:

# Prevent orders from being modified
Order.with_scope(:find => {:conditions => {:readonly => true}}) do
  create_invoice(order)
  bill(order)
  adjust_stock(order)
end

This assists in the prevention of the order from accidentally being changed. So… see where it fits in with your code, and try it out!

Using with_options

Another handy method is with_options. I’ve been using this in my route definitions, as I usually map more than one action per controller. However, you can use this in more than your routes.rb file. Let’s say you wanted to set the null option to false for all fields in a create_table migration…

def self.up
  create_table :comments do |table|
    table.with_options(:null => false) do |t|
      t.column :name, :string
      t.column :body, :text
      t.column :ip,   :string
    end
  end
end

It either adds a hash as the last parameter, or adds values into an existing hash parameter. Nifty.

Using &: (Symbol#to_proc)

I remember Chris mentioning the use of &: in his updated permalink method—so I’ve seen this before, but had forgotten about it. However, after seeing it again, it really does look pretty cool. It’s somewhat self explanatory, but here are a few examples to drive it home:

# Without using to_proc
%w{RYAN HEATH}.map {|word| word.downcase}
# => ["ryan","heath"]
users.map {|person| person.name}
# => ["Ryan","Amie","Heath"]

# With using to_proc
%w{RYAN HEATH}.map(&:downcase)
# => ["ryan","heath"]
users.map(&:name)
# => ["Ryan","Amie","Heath"]

Lookup Constants (“compile-time” caching)

This is a handy way to alleviate your application from executing the same query multiple times. For instance, lets say you have a states table that contains a short_name (state abbreviation) and a long_name (full state name). This may be something used in a registration form, or a purchasing form, or an address form, or whatever. I think it’s safe to assume this is a rather static table, so instead of getting this information from the database each time, we can cache the query results into a constant when the class definition is executed.

class State < ActiveRecord::Base
  STATE_LOOKUP = self.find(:all, :order => "long_name").map do |s|
    [s.long_name, s.short_name]
  end
  # ...
end

You can access your constant by calling State::STATE_LOOKUP.

State::STATE_LOOKUP
# => [["Alabama","AL"],["Alaska","AK"],["Arizona","AZ"] ... ["Wyoming","WY"]]

And then in a random form, you can use the constant to fill a drop down, rather than querying this information each time the form is loaded.

<%= form.select("state", State::STATE_LOOKUP) %>

Ok, I think that’s enough for now. I have a few more, but I’m going to split them up into several posts so it’s not too overwhelming all at once. I should have at least two more posts on the topic, but maybe three. Hopefully you’ve found something useful already, but if not, maybe you will in the next one.

Feeling good about less lines of code

At the Rails Edge conference, one of the speakers mentioned how, as a young programmer, there was no better feeling than to write a program with an enormous LOC count. It made him proud. And I tend to agree. I remember first learning C/C++ and how good it felt to have a rather large program compile successfully. “The more the better,” I thought. Well, that’s hardly the case. Software development entails writing less and less LOC, intentionally. The creator(s) of Rails have made some logical assumptions that have