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