Squirrel - Once More, with Feeling!
Posted by Jon Yurek
Jan 12
I admit, the first iteration of Squirrel wasn’t really as super fabulous as I thought it would be. Because of how I was using the blocks, you couldn’t do a simple thing like access params. And since half the fun of it was being able to make good looking, flexible queries, not being able to use params was a giant pain.
Now, however, I’ve managed to mix the clean, functional look of instance_eval with the husky utilitarianism of params to come up with a happier, shinier Squirrel:
1 2 3 4 |
users = User.find(:all) do blog.title == params[:blog_name] end |
And what’s that in the trees, gracefully swinging from vine to vine? It’s our friends any and all here to give us grouping blocks!
1 2 3 4 5 6 7 |
site = Site.find(:first) do any { domains.hostname == params[:hostname] domains.hostname == "www.#{params[:hostname]}" } end |
All the functions you’d expect to be able to use in your controller are available (well, as long as you actually are in your controller, anyway; squirrels aren’t miracle workers)—params, session, etc.
You can use the unary minus to negate any condition or block, and you can also use it to do a descending order_by
1 2 3 4 5 6 7 8 |
Post.find(:all) do -any { title =~ /^OMG/ id == 4 } order_by -created_on end |
This is a major rewrite from the original code and cleaned up things in a very good way. And what’s more, we’re using it in real code now, so I have a fire under my ass to keep it in fighting shape.
The SVN repo is https://svn.thoughtbot.com/plugins/squirrel/trunk for all of you itching to try it out.
Comments on this post
Jan 18
jarecare said,
After looking in your SVN repository I see you have 1 test. Why would I invest in a plugin that has 1 test? Are you sure this works?
Jan 18
ben said,
Why would you use a framework whose documentation is slightly above pitiful? Don’t be rude. Nobody is holding a gun to your head. Not every project enters the wild 100% ready-to-go. If it did, we wouldn’t have access to the great tools we do today.
Jan 18
jyurek said,
Heh, he didn’t mean any harm by that. He’s just really gung-ho about testing.
FWIW, I have added a bunch of tests to Squirrel today, inspired by that comment.
Jan 19
jarecare said,
Hey benny, I’ll take tests over documentation any day.
Documentation doesn’t prove something works, tests do.
Jan 26
Eric Wagoner said,
Do you know how this differs from Ezra’s ez_where?
http://opensvn.csie.oarg/ezra/rails/plugins/ez_where/
Jan 27
Ryan said,
Jarecare, tests don’t always prove code works. A statement thus indicates to me you perhaps haven’t had a lot of experience testing, eh?
Jan 27
Ryan said,
btw, love the title of your blog :)
Jan 28
Jon Yurek said,
Eric, if you mean about the internals, no, I don’t know how different they are. I’ve specifically not viewed ez_where’s source, as I wanted to write this without preconceived notions of how it should work.
On the outside, though, the biggest difference is that the block you pass to Squirrel doesn’t take a parameter. That is, instead of “user.username” in ez_where, you simply say “username” in Squirrel. It’s not a huge difference, but I think it lends itself to cleaner code that way.
The comparison operators are pretty much the same. I’m not sure if ez_where has any negation method, though.
Squirrel will make sure that all of your conditions, even the ones that are deep inside associations, will have the correct table reference—I’m unaware if ez_where does that. We do both use the same method for finally performing the query, which is to pass the calculated conditions/includes/etc to the original AR::Base#find method, though. It is my intention to eventually generate full SQL statements and simply use find_by_sql or similar, though I’m not sure how feasible that will be.
I hope that answers your question.
Feb 03
Jake said,
Amazing work Jon. And to answer the above posters question, ez-where cannot join on the same table, or in more technical terms “perform cascaded eager loading An example is if you had a table of Persons, and wanted each person to be able to have a spouse and children, in ez-where this would not work. We have been asking for such support for a long time …
There is only one gripe I have with squirrel and that is that it doesn’t seem to be able to work with paginating_find. Jon Do you think it’s possible for squirrel to support passing the” argument into the block? ez_where has this and maybe I’m mistaken and squirrel does too, but I noticed in the ‘execute’ class function it only grabs args.first . Any Ideas?
Sorry, comments are closed for this article.
© 2000 - 2009 by thoughtbot, inc.
written by a bushel of tiny robots
Come “ride the toad” on Hoptoad, the app error app.
Thunder Thimble: Brand monitoring for social media.
Widgetfinger: Simple content management for simple websites.
Tee-Bot, funny shirts your friends won't understand!
Umbrella Today: “It’s like totally the simplest weather report ever, Julie.”
Thoughtbot
thoughtbot is a technology consulting firm that provides web application development and design services. We focus on building modern systems, embracing good ideas and delivering elegant solutions.
Interested in learning Rails?
Sign up for our beginning or advanced training.
Archives