# Complex Active Record Associations

**URL:** <https://www.ruby-forum.com/t/complex-active-record-associations/143774>\
**Category:** Rails\
**Created:** [July 22, 2008, 5:26pm UTC](https://www.ruby-forum.com/t/complex-active-record-associations/143774 "2008-07-22T17:26:45Z")\
**Posts on this page:** 1\
**Page:** 1

<div class="post-metadata">

**Author:** ![jcernelli](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/j/73ab20/32.png) [@jcernelli](https://www.ruby-forum.com/u/jcernelli)\
**Post date:** [July 22, 2008, 5:26pm UTC](https://www.ruby-forum.com/t/complex-active-record-associations/143774/1 "2008-07-22T17:26:45Z")

</div>

Hi, I have a weird situation that I’m hoping to find a better way to  
solve.  
I have a situation where I need to only allow users to have certain data  
based on a division. I think I’m using finder\_sql way too much though  
and  
there has to be a better way.

Here’s the setup:

# User may be an admin, in which case they belong to ALL divisions

class User \< ActiveRecord::Base  
has\_and\_belongs\_to\_many :divisions  
end

class Division \< ActiveRecord::Base  
has\_and\_belongs\_to\_many :users  
has\_many :departments  
end

class Department  
belongs\_to :division  
has\_many :courses  
end

class Course \< ActiveRecord::Base  
belongs\_to :department  
end

I want to be able to make sure that a user is only ever to  
edit/view/delete  
courses that are within divisions that they are members of. I ended up  
with  
this, but it smells bad to me, and I’m hoping there is a better way:

# User may be an admin, in which case they belong to ALL divisions

class User \< ActiveRecord::Base  
has\_and\_belongs\_to\_many :divisions

has\_many :courses,  
:finder\_sql =\> ‘select courses.\*  
from courses,  
divisions\_users,  
roles\_users,  
divisions,  
departments  
where departments.id = courses.department\_id  
and  
departments.division\_id = divisions.id  
and  
divisions.id =  
divisions\_users.division\_id  
and  
divisions\_users.user\_id =  
roles\_users.user\_id and  
if(roles\_users.role\_id =  
3,1,divisions\_users.user\_id = #{id})’  
end

The if(roles\_users.role\_id = 3,1,divisions\_users.user\_id = #{id}  
determines  
if the user is an admin and takes appropriate measures.

This works fine as I can say:

# Select a course that the user has valid access to

user.courses.find(params[:id])

# Return a list of all courses the user should see

user.courses

One of the problems with this method is I am stuck with basic find by  
id’s.  
If I add anything more complicated (i.e. find :all, :conditions) the  
scheme  
breaks. Also,relying on hard coded SQL will make the app a little more  
brittle. Am I barking up the wrong tree? This is a pattern that recurs  
through our app so if there is a better way™ I’d like to find it,  
rather  
than having lots of SQL hanging out in my models.

Thanks in advance!  
Joe
