Access to mixed in method straight after its been mixedin?

Hi,

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

Greg H. wrote:

    protected
  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.


We develop, watch us RoR, in numbers too big to ignore.

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

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?

Is it really a basic “class” level context ruby rule that I’m not
understanding correctly? or is it something to do with the mixin
approach
and how the “base.class_eval do” concept works?

BTW - I thought I read that an “include” includes the methods as if they
were a “superclass” - would it be something to do with this? (i.e. in
terms
of understanding why I get the error on the line mentioned)

Thanks again
Greg

Greg H wrote:

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


We develop, watch us RoR, in numbers too big to ignore.

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:

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.


We develop, watch us RoR, in numbers too big to ignore.

thanks Mark