Context based filters?

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

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

Caio Chassot 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.

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

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

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