# Context based filters?

**URL:** <https://www.ruby-forum.com/t/context-based-filters/69377>\
**Category:** Rails\
**Created:** [September 20, 2006, 5:49pm UTC](https://www.ruby-forum.com/t/context-based-filters/69377 "2006-09-20T17:49:06Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![bartb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/848f3c/32.png) [@bartb](https://www.ruby-forum.com/u/bartb)\
**Post date:** [September 20, 2006, 5:49pm UTC](https://www.ruby-forum.com/t/context-based-filters/69377/1 "2006-09-20T17:49:06Z")

</div>

I’m looking for a way to DRY up some of my controller code.  
I’m having problems with code that keeps coming back where I have to  
check  
some very similar context dependant conditions. It can’t be moved into a  
filter because then it depends on a session variable, then on a  
parameter, …  
So I was wondering: is there some way to make context based filters? Or  
should I just make a method that gets called with the proper parameters.  
But is redirect\_to safe enough then? Does it stop the control flow in  
the  
calling function?  
I would have something like this in the controller

def do\_the\_checks(params)  
…  
if !okay  
redirect\_to # the page for the bad situations  
end  
end

def some\_method  
do\_the\_checks(params\_in\_this\_context)

# now do stuff in a check environment

end

Bart

---

<div class="post-metadata">

**Author:** ![bartb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/848f3c/32.png) [@bartb](https://www.ruby-forum.com/u/bartb)\
**Post date:** [September 20, 2006, 7:15pm UTC](https://www.ruby-forum.com/t/context-based-filters/69377/2 "2006-09-20T19:15:19Z")

</div>

On 2006-09-20, at 12:38 , Bart B. wrote:

> It can’t be moved into a  
> filter because then it depends on a session variable, then on a  
> parameter, …  
> So I was wondering: is there some way to make context based filters?

Can you be more specific in your example?

Filters run in the context of the controller so they have access to  
session and params just fine.

class WhateverController  
before\_filter :foobar

…

def foobar  
return if session[:foo] or params[:bar]  
do\_stuff  
return false unless everything\_ok?  
end  
end

---

<div class="post-metadata">

**Author:** ![bartb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/848f3c/32.png) [@bartb](https://www.ruby-forum.com/u/bartb)\
**Post date:** [September 21, 2006, 8:52am UTC](https://www.ruby-forum.com/t/context-based-filters/69377/3 "2006-09-21T08:52:56Z")

</div>

Caio C. wrote:

> Filters run in the context of the controller so they have access to  
> session and params just fine.

Right. In one controller I have if statements like:  
if authenticate\_as\_group or (authenticate\_as\_normal and  
(Project.find(params[:id]).research\_group\_id ==  
Person.find\_by\_login(session[:login]).research\_group\_id))

if authenticate\_as\_group or (authenticate\_as\_normal and  
(Project.find(@connection.project\_id).research\_group\_id ==  
Person.find\_by\_login(session[:login]).research\_group\_id))

if authenticate\_as\_group or (authenticate\_as\_normal and  
(Project.find(project\_id).research\_group\_id ==  
Person.find\_by\_login(session[:login]).research\_group\_id))

Notice how I have 3 different ways of coming up with the right project.  
authenticate\_as\_group is a method that checks that users have more  
rights  
than those that authenticate\_as\_normal.

Can this be done with a simple method I call that aborts the execution  
of  
further methods when the user cannot be authenticated?

Bart

---

<div class="post-metadata">

**Author:** ![bartb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/848f3c/32.png) [@bartb](https://www.ruby-forum.com/u/bartb)\
**Post date:** [September 21, 2006, 11:45am UTC](https://www.ruby-forum.com/t/context-based-filters/69377/4 "2006-09-21T11:45:16Z")

</div>

Try using a method in the application model instead

---

<div class="post-metadata">

**Author:** ![bartb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/848f3c/32.png) [@bartb](https://www.ruby-forum.com/u/bartb)\
**Post date:** [September 21, 2006, 12:05pm UTC](https://www.ruby-forum.com/t/context-based-filters/69377/5 "2006-09-21T12:05:20Z")

</div>

removed\_email\_address@domain.invalid wrote:

> Try using a method in the application model instead

But what if I notice the user does not have enough rights? Can I stop  
everything in the controller that called the validation method?  
Otherwise I am just putting that condition in a separated method and I  
call  
it from almost every method, that does not feel very DRY to me.  
Everything  
points towards filters here but they can’t be used…

Bart

---

<div class="post-metadata">

**Author:** ![bartb](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/b/848f3c/32.png) [@bartb](https://www.ruby-forum.com/u/bartb)\
**Post date:** [September 21, 2006, 12:29pm UTC](https://www.ruby-forum.com/t/context-based-filters/69377/6 "2006-09-21T12:29:22Z")

</div>

If logic to resolve project ID differs in all actions, I would do  
smth like that:

class SomeController \< ApplicationController  
def some\_action  
return redirect\_restricted unless authorize\_access(params[:id])  
# rest of code goes here…  
end

def other\_action  
# …  
# some code that sets @project\_id  
# …  
return redirect\_restricted unless authorize\_access(@project\_id)  
# rest of code goes here…  
end

private

def authorize\_access(project\_id)  
return authenticate\_as\_group ||  
(authenticate\_as\_normal &&  
Person.project\_member?(session[:login], project\_id)  
end

def redirect\_restricted  
redirect\_to ‘/no\_access.html’  
end  
end

class Person \< ActiveRecord::Base  
def self.project\_member?(login, project\_id)  
return 0 \< count(:conditions =\> [‘persons.login = ? and  
projects.id = ?’, login, project\_id],  
:joins =\> ’ JOIN projects ON (projects.research\_group\_id =  
persons.research\_group\_id)’ )  
end  
end

2006/9/21, Bart B. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid):
