# With\_scope and a special relationship

**URL:** <https://www.ruby-forum.com/t/with-scope-and-a-special-relationship/109243>\
**Category:** Rails\
**Created:** [July 12, 2007, 5:22pm UTC](https://www.ruby-forum.com/t/with-scope-and-a-special-relationship/109243 "2007-07-12T17:22:36Z")\
**Posts on this page:** 3\
**Page:** 1

<div class="post-metadata">

**Author:** ![carlosparamio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/f1d935/32.png) [@carlosparamio](https://www.ruby-forum.com/u/carlosparamio)\
**Post date:** [July 12, 2007, 5:22pm UTC](https://www.ruby-forum.com/t/with-scope-and-a-special-relationship/109243/1 "2007-07-12T17:22:36Z")

</div>

Hi!

I have a little problem with two specially related models and an  
accesor for one of them.

In our application, we have users (with a rights/roles subsystem) and  
documents. For each document, we have some users related to it, each  
one playing one role in that document. Some of them:

class Document \< ActiveRecord::Base

belongs\_to :adviser, :class\_name =\> ‘User’, :foreign\_key =\> ‘adviser\_id’  
belongs\_to :owner, :class\_name =\> ‘User’, :foreign\_key =\> ‘owner\_id’

end

Documents are related to users this way, but users are related to  
documents thinking that a user has a document if he participe in some  
of the posible roles (adviser, owner…). But some special users have  
access to more documents that those ones (for example, they can have  
access to all documents created and associated on his office, that  
it’s another attribute of both the document and the user models). So,  
instead of use has\_many :documents on User model, we created the  
following method on the User model:

class User \< ActiveRecord::Base

def documents  
if self.can(‘view all documents’)  
Document.find :all  
elsif self.can(‘view all office documents’)  
Document.find :all, :conditions =\> { :office\_id =\> self.office\_id  
}  
else # show only documents with direct user participation  
Document.find :all, :conditions =\> “(adviser\_id = #{self.id} or  
owner\_id = #{self.id})”  
end  
end

end

This works very well, but now we have a little problem. We want to use  
the User::documents method by adding some additional conditions or  
other find parameters, because we use customizable pagination, and a  
selector to allow the users to filter the documents. Something like:

current\_user.documents :conditions =\> ‘status = 3’, :limit =\> 20

We first tried to use with\_scope:

def documents(options = {})  
with\_scope :find =\> options do  
if self.can(‘view all documents’)  
Document.find :all  
elsif self.can(‘view all office documents’)  
Document.find :all, :conditions =\> { :office\_id =\> self.office\_id  
}  
else # show only documents with direct user participation  
Document.find :all, :conditions =\> “(adviser\_id = #{self.id} or  
owner\_id = #{self.id})”  
end  
end  
end

But didn’t work. Of course, we can create a method with all the  
possibilities as parameters, and merge the conditions, but that is  
boring (and doesn’t look well).

Is there any other “Ruby-way” alternative?

Thanks!

---

<div class="post-metadata">

**Author:** ![carlosparamio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/f1d935/32.png) [@carlosparamio](https://www.ruby-forum.com/u/carlosparamio)\
**Post date:** [July 12, 2007, 5:34pm UTC](https://www.ruby-forum.com/t/with-scope-and-a-special-relationship/109243/2 "2007-07-12T17:34:37Z")

</div>

Ok, describing you the problem I found a solution:

class User \< ActiveRecord::Base

def documents(options = {})  
Documents.find\_by\_user(self, options)  
end

end

class Document \< ActiveRecord::Base

def self.find\_by\_user(user, options = {})  
with\_scope :find =\> options do  
if user.can(‘view all documents’)  
find :all  
elsif user.can(‘view all office documents’)  
find :all, :conditions =\> { :office\_id =\> user.office\_id }  
else  
find :all, :conditions =\> “(adviser\_id = #{user.id} or  
owner\_id = #{user.id})”  
end  
end  
end

end

It seems that with\_scope :find only worked on the Document model. I  
don’t know exactly why, because my knowledge about with\_scope is  
minimum.

Anyway, I will grateful any suggestions.

---

<div class="post-metadata">

**Author:** ![carlosparamio](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/c/f1d935/32.png) [@carlosparamio](https://www.ruby-forum.com/u/carlosparamio)\
**Post date:** [July 12, 2007, 6:13pm UTC](https://www.ruby-forum.com/t/with-scope-and-a-special-relationship/109243/3 "2007-07-12T18:13:42Z")

</div>

Ok, my last approach lets me use find parameters, but I can’t use  
other ActiveRecord methods like paginate:

current\_user.documents.paginate …

because documents returns an array, and paginate doesn’t exist

If I use any other relationship defined with has\_many, I can use  
ActiveRecord methods, because what it returns is an ActiveRecord class  
with predefined conditions (doesn’t it?). For example, I can use:

current\_user.roles.paginate …

On 7/12/07, Carlos P. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> owner\_id = #{user.id})"
> 
> Anyway, I will grateful any suggestions.

–  
Carlos Alberto Paramio Danta .–.  
[http://www.sinfoniadebits.com/](http://www.sinfoniadebits.com/) |o\_o |  
email & jabber: carlosparamio @ [gmail.com](http://gmail.com) |:\_/ |  
Web D. & Solutions - Learning // \   
----------------------------------------( | | )–  
Fingerprint 41C6 D2BE 7DE7 AB61 C23F /'\_ _/`  
F697 5A1D 1849 01B8 D318 \_**)=(**_/
