views:

377

answers:

4

Hi I am trying to add a filter to a controller that is based on a certain role (using role_requirement) and then on the company_id that each user has.

So basically I need something like this:

require_role "company" ** This is working fine
  before_filter :company_required

def company_required
  unless current_user.company_id == Company.find(params[:id])    
end

end

The error I am receiving undefined method `company_id' for nil:NilClass

I would appreciate any guidance. Thanks

A: 

I would try a couple of things:

  • unless current_user.company == Company.find(params[:id]). Note I'm calling company on the current_user object, not company_id. Also, params is a hash and so you need to access it via [].
  • unless current_user.company_id = params[:id]>/code>. Arguably this is better since we're not making a request to the database to find the Company instance.
  • If non of that works, try using ruby-debugger to see what gets returned and evaluated at each point.
hgimenez
Sorry I did a terrible job putting this code in: before_filter :company_required def company_required unless current_user.company_id == Company.find(params[:id]) endendThe error I am receiving is: undefined method `company_id' for nil:NilClass (same for company as an object)I don't think I am calling current_user.. I am a newbie so I am not sure what I am doing wrong I appreciate any help.
After editing your original post, it's clear that the issue is with current_user, which is nil. You are basically calling a model method on nil, which doesn't quite work. You are missing a before_filter that sets up current_user. Go through the docs on whatever authentication system your using to set that up (authlogic, clearance, etc).
hgimenez
A: 

Without knowing the error, it's near impossible to diagnose. Here are some suggestions:

require_role "company" # This is working fine

then before_filter :company_required
def company_required
  unless current_user.company_id == params[:id].to_i #cast to int, to be sure
  redirect_to ('/')
end

Also, make sure that you have a before_filter set up to actually get current_user, otherwise you might get an error like:

Error trying to get nil.company_id

If that's the error, then current_user is nil, likely because it was never set.

Mike Trpcic
A: 

I'm assuming that you're using RESTful Authentication because you're referencing "current_user" and it looks like that isn't being defined.

In looking at the code for that plugin, it looks like that is set in the AuthenticatedSystem module. My guess is that you aren't including that in your controller.

According to the code that's automatically generated for the sessions controller, you should be adding "include AuthenticatedSystem" to your application controller (so it's available to all controllers).

Here is the code block from a generated sessions controller from RESTful Authentication.

# This controller handles the login/logout function of the site.  
class SessionsController < ApplicationController
  # Be sure to include AuthenticationSystem in Application Controller instead
  include AuthenticatedSystem
Carlos
+1  A: 

If a user is not logged in, current_user will be nil. You will have to guard against that case. There's also something missing here. Regardless of what the method called by the filter returns, the action will always proceed. With the exception of a method that calls render or redirect in the filter.

Here is a working filter that does what you're trying to do, assuming you have a named route called denied.

require_role "company" ** This is working fine
  before_filter :company_required

def company_required
  redirect_to denied_url unless logged_in? && current_user.company_id == Company.find(params[:id])    
end

You can add a route by adding the following to config/routes.rb before the default route block. You can use an existing controller or create a new one if you want. This is what I usually use:

map.denied '/denied', :controller => "home", :action => "denied"

As others have stated it looks like you're using Restful Authentication. You might find it helpful to take a look at documentation to better understand the login process. The short version is that a user will submit a form identifying them as a member of your application, to the sessions_controller which sets current_user. If you ran the generator you should access to the above mentioned logged_in? method.

sessions_controller and current_user may be something different in your application is you you gave the Restful Authentication generator differenet arguments.

EmFi