Where Plugin
January 2nd, 2006
UPDATE: I had to disable comments, because I was getting spammed with hundreds of “cool site” messages. Feel free to contact me in any other way.
Working with RubyOnRails is a really wonderful way of developing applications. The plugin system allows extensions without modifying the core of rails.
Here’s my second plugin: WherePlugin
It’s based on some code by Ezra Zygmuntovic extended by me, further extended by Ezra and packaged as a plugin.
It allows for easier creation of the :conditions => … clause in ActiveRecord find statements.
Here’s how to use it:
c = InVisible::Cond.new do
year '>', 2005
name 'like', 'Foo%'
end
Model.find(:all, :conditions => c.where )
or in a combined form:
Model.find_with_conditions(:all) do
year '>', 2005
name 'like', 'Foo%'
end
Installation
$cd /my/rails/project
$ruby script/plugin discover
$ruby script/plugin install -x where
The subversion repository is located at http://invisible.ch/svn/projects/plugins/where
Usage
You can use the following types of clauses in the definition of the Condition block:
- name ‘operator’, value
- name ‘between’, value, value
- sql ‘some sql statement’, value
Examples:
- first_name ‘=’, ‘Ezra’
- start_date ‘between’, ’2006-01-01′, ’2006-01-30′
- last_name ‘like’, ‘Zyg%’
- sql ‘hosts.id = something.id’
You can extend an existing condition block like this:
c = Cond.new
c < < ['name', 'Jens-Christian']
c << ['age', '>', 30]
Caveats
There is one caveat, if you use self in the block:
Task.find(:all, :conditions => ["project_id = ?", self.id] )
Task.find_with_conditions(:all) do
project_id '=', self.id
end
will break, because self inside the block will refer to another object. A workaround is to use temporary variables:
self_id = self.id
Task.find_with_conditions(:all) do
project_id '=', self_id
end
I will see, if there is a better solution for this.
Revision history
v. 0.2 (svn 36), 2.1.2006
- Added Ezra’s Cond Class
- removed the Where Class (breaking old code, but the Cond class is nicer)
- fixed the Model.findwithconditions method to use the Cond class
Comments, ideas etc. very welcome
Technorati Tags: rubyonrails, sql
Entry Filed under: Uncategorized

12 Comments
1. Scott | March 1st, 2006 at 04:10
I’m using your where plugin in a small webapp (thanks!)
Using the install command
ruby script/plugin install -x wheregives me the trunk revision – is there a variation on this to allow me to checkout a specific revision (e.g. 36 for 0.2)?RailsEngines uses the more standard trunk, branches, tags etc. structure so I can use the url to determine the tag I want to checkout.
Basically I need to be sure that my plugin code is only updated when I want it to be (so I can test the integration with my application).
Also, your server was down for a while today. I use SwittchTower to deploy – since this pulls the source from svn my deployments were failing until your site came back up. This experience is making me reconsider the use of svn:externals for plugins since doing so leaves me at the mercy of multiple servers, any of which can cause my deployment to fail.
I guess if I do an actual checkout of the code (more likely an export/import) I can get around both of these problems at the expense of it becoming a little more difficult to receive updates.
Cheers,
Scott
2. Administrator | March 1st, 2006 at 08:13
Thanks for your comments. When I’ll release the next version, I’ll switch to the trunks/tags format to alleviate this problem.
My hoster had a
network blip – so everything was gone for a while. I don’t know the best way around situations like that.
It looks like the whole plugin system needs some thought in order to make it more safe to use.
jc
3. Benjamin | April 11th, 2006 at 02:55
Your plugin is definetely useful for people who want an alternative style to crafting their conditions. You could actually put conditions in a seperate file entirely if you wanted a really clean looking file and just have condition definitions elsewhere. That’d be an interesting way to organize them. Thoughts?
4. iktorn | May 19th, 2006 at 11:43
The plugin is awesome. I was looking for a clean way to add multiple conds to find. BUT – 2 things:
I use:
name 'like', '%' + params[:search] + '%' unless params[:search].nil
Task.findwithconditions(:all) do
end
I get a SQL error it produces ‘AND ()’.
5. iktorn | May 19th, 2006 at 11:49
Update – I think the no 1 is the issue with method_missing…
I don’t know how to fix it though
6. Administrator | May 23rd, 2006 at 06:28
iktorn, yes you are right, params is not accesible in that context. Take a look at Ezra’s ezwhere plugin (http://agilewebdevelopment.com/plugins/ezwhere) which has this problem solved (and expands the whole thing with a beautiful ruby like way of doing the query)
I’ll take a look at the second problem when I find some time
7. iktorn | May 25th, 2006 at 10:20
A new bug found… :)
options = args.last.class.is_a?(Hash) ? args.pop : {}should be
options = args.last.is_a?(Hash) ? args.pop : {}8. Administrator | May 25th, 2006 at 17:49
Thanks iktorn, I commited a new version with 2 out 3 of your problems fixed. I’ll look into the third (availability of variables in block) later
jc
9. Alan | May 31st, 2006 at 20:17
So exactly how do you use the examples? Do you put your example code in a view protected with <% markup? I could not get it to work.
10. Jens-Christian Fischer | May 31st, 2006 at 23:22
Alan, I’m not sure I understand your question. I usually use this plugin in my models when there’s a
statement that has a very complex :conditions => {} part. Does that answer your question? Otherwise, please provide more information on what you are trying to do
11. Michael Mahemoff | August 29th, 2006 at 20:02
For anyone who’s interested, here’s how I got the internal test (where_test.rb) running for mysql.
… Green Bar!
12. Going Up » Simplifi&hellip | October 25th, 2006 at 15:27
[...] So I’ve tried Ezra’s “ez_where” and InVisible’s “where” plugins, but in the end I just couldn’t get past the hackish feeling I got when I used them. [...]
Trackback this post