Access to mixed in method straight after its been mixedin???

Greg Hauptmann wrote:

Can't I access methods directly after they have been mixed in?

In the code below I get an error at the marked location "undefined local variable or method `current_user' for ApplicationController:Class" even though I've already mixed in the variable into the class. Note that when I use "current_user.login" in another place, for example in an action in a specific controller, it works fine, but just not here in the ApplicationController directly after the mix in.

Can you spot why at all? Tks in advance.

============================================ class ApplicationController < ActionController::Base   include ActiveRbacMixins::ApplicationControllerMixin   u = current_user.login <=== ERROR OCCURS HERE end

module ActiveRbacMixins   module ApplicationControllerMixin     def self.included(base)       base.class_eval do         protected           def current_user             return @active_rbac_user unless @active_rbac_user.nil?             @active_rbac_user =                     if session[:rbac_user_id].nil? then                       ::AnonymousUser.instance                     else                       ::User.find(session[:rbac_user_id])                     end             return @active_rbac_user           end       end     end   end end

current_user is an ApplicationController instance method, which you can't use in the class context of a class definition. Perhaps you want to put the setting of u (or @u) in a before_filter.

Tks - but I still don’t quite understand then why the following works say however:

PS. just did some more testing and have proved to myself that “current_user” (created by a mixin with the “class_eval” concept) can’t be accessed via a “before_filter”, however and can access it and see it find if I put it within a method. See code snippet below.

Can anyone explain why this occurs? Also how can I get access to this variable in a “before_filter” or directly within the superclass, as I dont’ want to have to try to put the same line of code in all the different actions :frowning:

class ContactsController < ApplicationController before_filter { Suberb.current_user_gregs = current_user.login } <== “ERROR HERE”

def edit Suberb.current_user_gregs = current_user.login <== ACTUALLY WORKS HERE ?

end . . . end

Greg H wrote:

PS. just did some more testing and have proved to myself that "current_user" (created by a mixin with the "class_eval" concept) can't be accessed via a "before_filter", however and can access it and see it find if I put it within a method. See code snippet below.

Can anyone explain why this occurs? Also how can I get access to this variable in a "before_filter" or directly within the superclass, as I dont' want to have to try to put the same line of code in all the different actions :frowning:

class ContactsController < ApplicationController     before_filter { Suberb.current_user_gregs = current_user.login } <== "ERROR HERE"

If you write a filter as block you have to use a controller parameter in order to access current controller instance methods.

   before_filter { |c| Suberb.current_user_gregs = c.current_user.login }

  def edit     Suberb.current_user_gregs = current_user.login <== ACTUALLY WORKS HERE ?   end

Yes, edit is a controller instance method that has access to current_user, another controller instance method.

You can now write:

   before_filter :edit

Greg H wrote:

Tks - but I still don't quite understand then why the following works say however:

=====     include ActiveRbacMixins::ApplicationControllerMixin     @a = 1     @b = @a <=== WORKS     u = current_user.login <=== DOESN'T WORK

You are in a class not an instance context here, so you can't access the current_user instance method.

Instance variables are normally associated with an instance of a class object, being initialized in the class' initialize method. But, as you have done, they can also be defined in the class context of a class definition. In this case the variables are like double-@ class variables, but are local to the class, and not accessible by descendent classes. e.g:

  class A            @a = 1            @@a = 2            def A.d              p @a              p @@a            end          end

         class B < A          end

A.d prints

1 2

While B.d prints

nil 2

I thought conceptually that the "include" along with the mixin'ed method of " base.class_eval do" was effectively injecting "current_user" into the class so that it would be effectively equivalent to the "@a" variable? Like the "@a=1" line seems to get run?

class_eval injects its receiver as self. Here the receiver is base, which is ApplicationController. Inside the class_eval block the current_user method has been defined as "def current_user", not "def self.current_user", so when the module is included current_user becomes an ApplicationController instance method.

It may have been done for some other reason, but in the way you're including the module there was no need to define self.included and use class_eval. All that needed to be done was to def the current_user method inside the mixin module.

thanks Mark