Patch test plugin: dynamic finders with belongs_to names

— July 2, 2006 at 23:07 PDT

Dynamic finders are pretty neat, but I've grown tired of having to think in terms of foreign keys instead of the names of belongs_to associations. So I fixed it.

This patch enhances dynamic finders to allow use of a belongs_to association name instead of having to use the foreign key attribute directly. For example, these two lines are equivalent:

posts = Post.find_all_by_author_id(
posts = Post.find_all_by_author(author)

Of course, that makes more of a difference when the association name and foreign key name differ more. But I think that makes dynamic finders a bit more transparent and easier to use.

I'll be submitting this as a patch fairly soon, but first I wanted to toss it out into the wild to see how well it works. I've written unit tests, but for something like this I'd feel just slightly better knowing a few people have given it a try first. So I've packaged the patch as a plugin to make it easy for you to try it out.


Give it a shot, and either email me or leave a comment here to let me know if it works or if it breaks something.

UPDATE: I've fixed the plugin so that the monkey patch loads properly now. If it wasn't working for you before, update to the new version and try it again now. Thanks!

10 commentspatch, plugins, rails

  1. Simon Harris2006-07-02 23:49:45


    Not sure I'll have time to test it much but it's something that's always bugged me and now you've fixed it :)

    Hope the patch gets in.

  2. Remco van 't Veer2006-07-03 01:05:06

    Why not say:

      posts = author.posts

    Can you give an example where I would want a find method like this instead?

  3. Ted2006-07-03 05:44:38

    Sweet! I'll definitely give it a whirl the next time I start up RadRails :-) Sadly, I've not touched a line of Rails code in so long, predating RailsConf even. I miss it :-\

  4. Carl Fyffe2006-07-03 08:01:01


    Check out his previous post about Working with the relationship model.

    This now makes a three line solution into a one liner. Very nifty.

  5. fabio2006-07-05 18:52:32

    This is wonderful! I wonder if it would be possible to do the same thing with this syntax:

    posts = Post.find(:all, :by => {:author => author})

    I tend to prefer this way, but it's probably just a preference. Also, not sure if this is out of the scope of this article.

    Thanks for your work.

  6. Josh Susser2006-07-05 19:34:06

    @fabio: Edge rails already supports half of what you want. You can now just pass a hash as as the value for the :conditions option, and the finder will turn it into the correct expressions for the WHERE clause. However I don't think it works with the belongs_to names. You should also check out the ez_where plugin for enhanced query conditions.

  7. fabio2006-07-05 19:58:15

    sorry for the double post, just an additional thought.

    posts = Post.find(:all, :by => {:author => author})

    could be refactored down using some fancy meta-programming footwork to:

    assume you've already done dhh = author.find_by_fname("David")

    and dhh == 12

    posts = Post.find(:all, :by => dhh)

    You could then do dhh.class to find out what type of object it is and use that to construct the sql:

    SELECT * FROM posts WHERE author_id = 12

  8. S. Brent Faulkner2006-07-06 19:00:40

    This did not work for me initially. As is, I got...

    undefined method `find_all_by_author' for Post:Class

    To get this to work I had to package the plugin a bit differently. I put the patch code in lib/dynamic_finders_with_belongs_to_names.rb and changed the contents of init.rb to just...

    require 'dynamic_finders_with_belongs_to_names'

    Then, it worked. Thanks for the patch (and for indirectly helping me sort out how to make my own work).

  9. Josh Susser2006-07-06 23:25:35

    Brent: oh duh. I was wondering why some people were having trouble loading the patch. I'll put together a new version with your fix. Thanks.

  10. Scott Burton2006-07-14 13:11:04

    Ah nice, it's the little things in life.

Sorry, comments for this article are closed.