0

So, here's my problem. I currently am building a simple authentication system for a rails site. I have 3 classes for this: Person, Session, and Role. In my Person model I have defined method_missing to dynamically capture roles according to this guide.

In my application_controller I have some logic to deal with logins and log-outs, the result of which gives me the currently logged in user via: @user = @application_session.person Where @application_session is the current session

Now in one of my controllers, I don't want anyone to be able to do anything unless they are an admin, so I included: before_filter @user.is_an_admin?

This raises a NoMethodError, even though I have method_missing defined in my model. I tried defining is_an_admin?, having it always return true as a test, and that works.

According to this question, I think the problem might have something to do with proxy associations. When I run: puts @user.proxy_owner I get a session object, since each user (Person) can have many sessions, and I got my user (Person) from the current session.

I am very confused why @user.is_an_admin? is not calling the method_missing method in my Person controller. Please let me know if you need more information or code snippets.

I am using Rails 3 on Ruby 1.9

Community
  • 1
  • 1
Trevor
  • 1
  • how is @user set? is there a filter before the before filter? – apneadiving May 17 '11 at 21:56
  • yes, `@user` is set in a before_filter in the application_controller, than `@user.is_an_admin?` is called in the reports_controller. I also tried `@user.is_an_admin?` in the index method of that controller for debugging purposes and received the same error. – Trevor May 18 '11 at 03:46

3 Answers3

0

I'd consider a method_missing an overkill for such task.

Now, if you have Session class, which belongs_to User, then you can have this:


class Session
  belongs_to :user, :extend => PermissionMixin
end

class User
  include PermissionMixin
end

module PermissionMixin
  def admin?
    if cond
      true
    else
     false
    end
  end
end

P.S. Check cancan, perhaps it'll suit your needs better.

Roman
  • 13,100
  • 2
  • 47
  • 63
  • That would probably suit my immediate needs, but I want to build this to be expandable. I want to be able to add more user roles later, without having to write an "is_a_role?" method for each one. I'll take a look at cancan, thanks. – Trevor May 18 '11 at 03:50
  • You can have method_missing in this mixin, I just don't like the concept. – Roman May 18 '11 at 06:22
0

I have solved this by moving the method_missing method to my application_controller.rb. I change the logic of the method a little to check for a user, and if found, dynamically check the role. If things were not kosher, I had the method redirect to root_url or return true if the user matched the requested roles.

Finally, in my reports controller, I used before_filter :is_an_admin? and got my desired results. However, I am still unclear as to why method_missing had to be defined in my application controller as opposed to directly in the Person (aka @user) model?

Castiblanco
  • 1,200
  • 4
  • 13
  • 32
Trevor
  • 1
0

I use a similar permissions check in my system to check the User > Role > Permissions association: User.current_user.can_sysadmin?

In my controllers I have to instead use: User.current_user.send('can_sysadmin?')

This may work for you as well.

Matt
  • 13,948
  • 6
  • 44
  • 68