Skip_before_filter (Do I need a lesson in modules/mixins?)

Gurus,

I am reading the O’Reilly book “Rails: Up and Running, 2nd Edition” and
the author told me to add the following line of code:

skip_before_filter :verify_authenticity_token

as follows:

class SlidesController < ApplicationController
skip_before_filter :verify_authenticity_token

This stopped me dead in my tracks as I realized I had no idea what was
going on. I am using Aptana (Eclipse) and so it can tell me that
skip_before_filter is defined in the module ClassMethods. I am assuming
that somehow this method (skip_before_filter) is mixed in?

The implementation is:
def skip_before_filter(*filters)
filter_chain.skip_filter_in_chain(*filters, &:before?)
end

What is *filters? Did I miss this in my ‘Learning R.’ book?

Anyway, I guessed that I was calling the method ‘skip_before_filter’
sometime during my controller’s construction. So I built a toy to
validate as follows:
####################BEGIN
test.rb###############################################
module Test
def call_me
puts “Mixin called”
end
end
module Test2
def call_me
puts “second mixin called”
end
end

class Tester
include Test, Test2
#call_me() #this call fails. This blows my theory…

def initialize
super
call_me()# this call works, but how would I call the other one?
#Test2::call_me()#this call fails
puts “A tester was built”
end

end

Tester.new
########################################END test.rb###########

output is:
Mixin called
A tester was built

Thanks for your help with my questions.

Cris

On Aug 12, 2009, at 14:50 , Cris S. wrote:

I am reading the O’Reilly book “Rails: Up and Running, 2nd Edition”
and

this is a ruby mailing list, not a ruby on rails mailing list. Please
post in the appropriate area.

On Wed, Aug 12, 2009 at 5:50 PM, Cris S.[email protected] wrote:

 skip_before_filter :verify_authenticity_token
   end

What is *filters? Â Did I miss this in my ‘Learning R.’ book?

This collects all of the arguments into an array called filters. You
can find more looking for “ruby splat” on google.

module Test2
  super
output is:
Mixin called
A tester was built

Rails uses a convention with modules similar to the following:

module FooBehaviors
def self.included(base)
base.extend(ClassMethods)
end
module ClassMethods
def foo
puts 42
end
end
end

class Bar
include FooBehaviors
foo
end

When FooBehaviors module is included, it also extends the including
class with the FooBehaviors::ClassMethods module. You can find out
more by looking at the differences between include and extend.

http://railstips.org/2009/5/15/include-verse-extend-in-ruby

Best,
Michael G.

On Thu, 13 Aug 2009 09:02:30 +0900, Ryan D. wrote:

On Aug 12, 2009, at 14:50 , Cris S. wrote:

I am reading the O’Reilly book “Rails: Up and Running, 2nd Edition” and

this is a ruby mailing list, not a ruby on rails mailing list. Please
post in the appropriate area.

He asked a Ruby question, using Rails code as an example. Please don’t
be unfriendly.

Cris S. wrote:

What is *filters? Did I miss this in my ‘Learning R.’ book?

def meth1(*args)
p args
end

meth1(1, 2, 3)

–output:–
[1, 2, 3]

def meth2(x, y, z)
puts x, y, z
end

args = [1, 2, 3]
meth2(*args)

–output:–
1
2
3

def meth3(x, y, *args)
p x, y, args
end

meth3(1, 2, 3, 4, 5, 6)

–output:–
1
2
[3, 4, 5, 6]

When FooBehaviors module is included, it also extends the including
class with the FooBehaviors::ClassMethods module. You can find out
more by looking at the differences between include and extend.

http://railstips.org/2009/5/15/include-verse-extend-in-ruby

Best,
Michael G.

Michael,

Thanks for your response. Your url was helpful and by following the
inheritance tree I found the code that includes skip_before_filter:

Base.class_eval do
[ Filters, Layout, Benchmarking, Rescue, Flash, MimeResponds,
Helpers,
Cookies, Caching, Verification, Streaming, SessionManagement,
HttpAuthentication::Basic::ControllerMethods,
HttpAuthentication::Digest::ControllerMethods,
RecordIdentifier, RequestForgeryProtection, Translation
].each do |mod|
include mod
end

but I still feel like skip_before_filter is a dangling method call in
the following code:

class SlidesController < ApplicationController
skip_before_filter :verify_authenticity_token

I tried creating a simple example (using what your url illustrated) but
it does not work. Here is my toy The first ‘call_me’ invocation is
what I am assuming is equivalent to the skip_before_filter call:

module Test

def self.include(base)
base.extend(ClassMethods)
end

module ClassMethods

def call_me
  puts "Class method"
end

end
end

module Test2
def call_me
puts “second mixin called”
end
end

class Tester
include Test, Test2
call_me()#toy.rb:23: undefined method `call_me’ for Tester:Class
(NoMethodError)

def initialize
super
call_me()
puts “A tester was built”
end

end

Tester.new

I should mention that I am seeing these ‘dangling’ calls more and more
as I look through what the scaffolding generated so I would like a clue!

Thanks,

Cris

Well I can reproduce that in irb, but no it doesn’t answer my question.

Anyone out there know the answer?

Thanks,

Cris

Jesús Gabriel y Galán wrote:

On Thu, Aug 13, 2009 at 4:19 PM, Cris S.[email protected] wrote:

I tried creating a simple example (using what your url illustrated) but
it does not work. �Here is my toy �The first ‘call_me’ invocation is
what I am assuming is equivalent to the skip_before_filter call:

module Test

�def self.include(base)

def self.included(base)

irb(main):016:0> module Test
irb(main):017:1>
irb(main):018:1* def self.included(base)
irb(main):019:2> base.extend(ClassMethods)
irb(main):020:2> end
irb(main):021:1> module ClassMethods
irb(main):022:2> def call_me
irb(main):023:3> puts “Class method”
irb(main):024:3> end
irb(main):025:2> end
irb(main):026:1> end
=> nil
irb(main):027:0> class Tester
irb(main):028:1> include Test
irb(main):029:1> call_me
irb(main):030:1> end
Class method
=> nil

Hope this helps,

Jesus.

On Thu, Aug 13, 2009 at 4:19 PM, Cris S.[email protected] wrote:

I tried creating a simple example (using what your url illustrated) but
it does not work. Here is my toy The first ‘call_me’ invocation is
what I am assuming is equivalent to the skip_before_filter call:

module Test

def self.include(base)

def self.included(base)

irb(main):016:0> module Test
irb(main):017:1>
irb(main):018:1* def self.included(base)
irb(main):019:2> base.extend(ClassMethods)
irb(main):020:2> end
irb(main):021:1> module ClassMethods
irb(main):022:2> def call_me
irb(main):023:3> puts “Class method”
irb(main):024:3> end
irb(main):025:2> end
irb(main):026:1> end
=> nil
irb(main):027:0> class Tester
irb(main):028:1> include Test
irb(main):029:1> call_me
irb(main):030:1> end
Class method
=> nil

Hope this helps,

Jesus.

No it is not the fact that the method call is not within another method
call that is tripping me up. It is that I cannot get it to work for me.

Consider the following code:
####################################
module Test

def self.include(base)
base.extend(ClassMethods)
end

module ClassMethods
def call_me
puts “Class method”
end
end
end

class Tester
include Test
call_me#toy.rb:23: undefined method `call_me’ for
Tester:Class(NoMethodError)
end

Tester.new
###################################

yields the following results:
toy.rb:24: undefined local variable or method `call_me’ for Tester:Class
(NameError)

Again I am assuming my ‘call_me’ is equivalent to my originally
referenced ‘skip_before_filter’.

Thanks,

Cris

pharrington wrote:

On Aug 13, 10:19�am, Cris S. [email protected] wrote:

I should mention that I am seeing these ‘dangling’ calls more and more
as I look through what the scaffolding generated so I would like a clue!

Thanks,

Cris

Posted viahttp://www.ruby-forum.com/.

Is it the fact that the method calls aren’t happening within another
method tripping you up? In Ruby, most everything happens at runtime,
class creation included. Also, everything’s an object. So when
something like

class Foo; some_ish; end

happens, Ruby is creating a new class, and some_ish is just being run
in the instance of the Class that is being created. (well it is more
complicated than that, but that should be enough to help understand
whats going on?). Its really no different than attr_accessor and
friends.

On Aug 13, 10:19 am, Cris S. [email protected] wrote:

I should mention that I am seeing these ‘dangling’ calls more and more
as I look through what the scaffolding generated so I would like a clue!

Thanks,

Cris

Posted viahttp://www.ruby-forum.com/.

Is it the fact that the method calls aren’t happening within another
method tripping you up? In Ruby, most everything happens at runtime,
class creation included. Also, everything’s an object. So when
something like

class Foo; some_ish; end

happens, Ruby is creating a new class, and some_ish is just being run
in the instance of the Class that is being created. (well it is more
complicated than that, but that should be enough to help understand
whats going on?). Its really no different than attr_accessor and
friends.

On Thu, Aug 13, 2009 at 8:40 PM, Cris S.[email protected] wrote:

No it is not the fact that the method call is not within another method
call that is tripping me up. It is that I cannot get it to work for me.

Consider the following code:
####################################
module Test

def self.include(base)
base.extend(ClassMethods)
end

You have the same typo: it’s self.included (note the final ‘d’).

Jesus.

Thanks everyone (especially Michael and Jesus)!

I missed the missing ‘d’. I put it in and it works!

And of course the ‘d’ is in the original code…

module ActionController #:nodoc:
module Filters #:nodoc:
def self.included(base)
base.class_eval do
extend ClassMethods
include ActionController::Filters::InstanceMethods
end
end

pharrington wrote:

On Aug 13, 2:40�pm, Cris S. [email protected] wrote:

Tester:Class(NoMethodError)
referenced ‘skip_before_filter’.

Thanks,

Cris

Then I’m confused as to what you’re still confused about? Jesus
already pointed out the typo: you need

def self.included(base)

versus

On Aug 13, 2:40 pm, Cris S. [email protected] wrote:

Tester:Class(NoMethodError)
referenced ‘skip_before_filter’.

Thanks,

Cris

Then I’m confused as to what you’re still confused about? Jesus
already pointed out the typo: you need

def self.included(base)

versus

This forum is not affiliated to the Ruby language, Ruby on Rails framework, nor any Ruby applications discussed here.

| Privacy Policy | Terms of Service | Remote Ruby Jobs