Exclusive Conditions for ActiveRecord’s has_many

I’ll start with some code.


class User < ActiveRecord::Base
  has_many :things, :exclusive_conditions => %q(`things`.user_id = #{id} OR #{admin?})
end

 

Assuming, we have 2 users, Alice and Bob.


user = User.find_by_username("alice") # => Alice is an admin.
user.id # => 1
thing = user.things.find_by_name("Bob's Thing")
thing.user_id # => 2, It's still bobs thing.

 

Now in my controller’s I can just say something like:


class ThingsController < ApplicationController
  # using restful_authentication or acts_as_authenticated here.
  before_filter :login_required
 
  def update
   @thing = current_user.things.find(params[:id])
   # ...
  end
end

 

Now I don’t have to write any other code to check ownership, AND an admin can
still play with anyone else’s things.

What I’ve done here is added an :exclusive_conditions option to
has_many. It’s not possible to express this idea with the :conditions
option.

Observe:


User.has_many :things, :conditions => ["your_condition = ?", "yes"]

 

Will result in SQL like:


SELECT * FROM things WHERE (user_id = 1) AND (your_condition = ‘yes’)

The “(user_id = 1) AND“ is hard coded. So I can’t say
(user_id = 1) OR (something_else)“ with has_many without writing out
the entire statement using :finder_sql.

But then if I do that, I lose all the fun proxy methods, preventing me from
doing things like user.things.find</tt> or <tt>user.things.create
which are of course, in the scope of that user.

Here’s the plugin, http://subvert.itred.org/has_many_exclusive_conditions/.

1 Response to “Exclusive Conditions for ActiveRecord’s has_many”


  1. Gravatar Icon 1 runmen

    Just what’s I’m need, thanks.

Leave a Reply