Close and Go BackBack to Viget

Simple named_scope Searching

Matt Swasey
Matt Swasey, Web Developer, January 15, 2010 2

One of the coolest aspects of named_scopes in ActiveRecord is their ability to chain together. One can chain a number of named_scopes onto each other, and the result is a single SQL query. Using this feature, I've come up with an easy way to do some simple searching.

To begin I'll create a search form with fields for searching on 'Artist' and 'Song title.'

<div>
  <% form_tag search_songs_path, :method => :get do %>
  <p>
    <%= label_tag "Artist" %><br/>
    <%= text_field_tag "search[by_artist]", params[:search].try(:[], :by_artist) %>
  </p>

  <p>
    <%= label_tag "Song title" %><br/>
    <%= text_field_tag "search[by_name]", params[:search].try(:[], :by_name) %>
  </p>

  <p>
    <%= submit_tag "Search" %>
  </p>
  <% end %>
</div>

This form will submit it's elements as GET parameters to a search action. This is a custom action, so we need to define it in our routes file:

map.resources :songs, :collection => {:search => :get}

And in app/controllers/songs_controller.rb

....
def search
  @songs = Song.search(params[:search])
  render :index
end
....

The search action will call Song.search, and pass the param values attached to :search.

Implementing the Search

We need a class method in our Song model that will find records based on our params. What I want is to turn this:

{:by_name => "Twist and Shout", :by_artist => "The Beatles"}

Into this:

Song.by_name("Twist and Shout").by_artist("The Beatles")

Here's what I came up with:

def self.search(params)
  params.keys.inject(scoped({})) do |found, k|
    params[k].blank? ? found : found.send(:"#{k}", params[k])
  end
end

And a named_scope for every key:

named_scope :by_artist, lambda {|name| {:conditions => {:artist => name}}}
named_scope :by_name, lambda {|name| {:conditions => {:name => name}}}

Let's step through what's happening in Song.search:

  1. Param's keys are iterated over, setting the initial value for inject to an anonymous scope.
  2. Iterating over the key names, we return the current collection 'found' if the current key has no value.
  3. If the key does have a value, the key name is called on the collection with it's corresponding value as the arguments. Since 'found' is always a scope, we can do this as many times as needed, creating our scope chain.

Conclusion

If I had to preform searching of a more complex nature, I might choose an library like ThinkingSphinx. If you want something quick, simple, and relativly flexible, I think this approach is worth a try.

Developer Resolutions for 2010

Ben Scofield
Ben Scofield, Technology Director, December 23, 2009 4

I am, to put it mildly, not a fan of the typical New Year’s resolution. Generally, it’s much too vague, it runs over much too long a time scale, and it’s not supported by appropriate subgoals (monthly, weekly, and daily). In effect, they’re feel-good affirmations, but they’ve got no teeth.

I’m always optimistic about well-structured and supported resolutions, however, and the start of a new year is the second-best time to launch them (the best time, of course, is today). Think of these as overarching priorities that can help guide your shorter-term planning efforts throughout the year to come; as you sit down at the beginning of every month, week, and day, these resolutions provide a framework to fit projects and tasks into.

So, without further ado, here are some suggested New Year’s resolutions for developers:

Have a new year

The "years of experience" requirement that so many HR departments rely on is bunk; we’ve all met developers who’ve been working continuously for a decade, but they’ve not grown at all. In effect, they’ve repeated the same year (or month, even) of experience over and over. Make a commitment that this year will be different!

Learn a new technology

The technical world presents boundless opportunities to learn, from new languages (as the Prags suggest), to new frameworks and applications. My personal pick for the most exciting area of development at the moment is the alternative database (e.g., NoSQL) scene, but there are changes afoot everywhere.

Practice your craft

The best way to improve at something is to practice deliberately – work at a task specifically designed to help you improve, pay careful attention to your results, and modify your performance appropriately when repeating the task. Note that this isn’t the same as, say, starting a side-project to learn a new web framework. If your goal is something other than pure practice, then you won’t actually be practicing.

Contribute to the community

There’s always a problem out there to be tackled, so start a new open-source project or contribute to one that already exists.

Test your JavaScript

OK, this one’s a bit more specific than the others, but let’s face it: most people don’t test their JavaScript. There’s been a surge of development in testing tools over the past year, so isn’t it about time you took a look at some of them?

Happy New Year!

User Goal Tracking in Rails with Vanity and Google Analytics

Tony Pitale
Tony Pitale, Web Developer, December 21, 2009 0

With the release of Vanity and the availability of the Google Analytics Data Export API, we now have two additional tools to further understand how users are navigating our web applications. I’d like to share how we go about comparing metrics tracked in Vanity to data pulled from Google Analytics with Garb.

Continue reading "User Goal Tracking in Rails with Vanity and Google Analytics"

Hackday: Intro to Ruby Meta-Programming

Justin Marney
Justin Marney, Web Developer, December 17, 2009 0

This past Saturday we hosted the third Hackday at Viget Labs (photos). For this round we decided to tackle meta-programming, one of the more mystical features of Ruby. We found, through several conversations at Hacknight, that people were getting the hang of Ruby through their work with Rails, but weren't clear on how things like the find_by_* methods were implemented. Unlike the previous Hackdays we took a more structured presentation approach, but that didn't reduce the usual amount of collaboration and discussion that makes Hackday unique. We even had a brave audience member do some live meta-programming!

The morning was divided up into two topics: The Ruby Object Model and Meta-Programming in Ruby. I covered the first section in an effort to lay down some foundational knowledge regarding Ruby's internals. Matt did a great job building on top of that material and was able to show some real world examples of meta-programming. He had an audience member come up and live code a pure Ruby implementation of attr_accessor and followed that up with a break down of how Rails uses meta-programming to dynamically build find_by_* methods.

Thanks to everyone who was able to make it to the event! If you weren't able to make it, or want to go over the topics we covered, we've put up our notes and code examples on GitHub. Feel free to email me or Matt with any follow up questions. We hope to see you all at the next HackNight.

Gifts For Your Nerd

David Eisinger
David Eisinger, Web Developer, December 16, 2009 5

Shopping for a nerd this holiday season? A difficult proposition, to be sure. We are, after all, complicated creatures. Fortunately, Viget Extend is here to help. Here are some gifts your nerd is sure to love.

Lacie iamaKey Flash Drive ($30)

If your nerd goes to tech conferences with any regularity, your residence is already littered with these things. USB flash drives are a dime a dozen, but this one’s different: stylish and rugged, and since it’s designed to be carried on a keychain, it’ll always around when your nerd needs it.

AeroPress ($25)

A simple device that makes a cup of espresso better than machines costing twenty times as much. Buy this one for your nerd and wake up to delicious, homemade espresso every morning. In other words, it's the gift that keeps on giving. If espresso gives your nerd the jitters, you can’t go wrong with a french press.

Continue reading "Gifts For Your Nerd"

We're the Developers

at Viget Labs. We write about web development trends, tips, best practices, industry events, and our projects — all with an emphasis on Ruby on Rails.

Contact Us

Have any questions, comments, ideas, or secrets to share? Let us know.


How many days in a non-leap year?

Sorry, you need to have Javascript enabled to use this form. (Don't blame us, blame the spammers!) If you'd like to contact us, please visit our Contact page.