Stack level too deep problem


#1

Hi all, I’m trying to overload the link_to function, (to disable link_to
if
the user has no access right)
this is my code, it work the first time I run the application, the
second
time I refresh the page I always get “stack level too deep error”

module UsersHelper
include ActionView::Helpers::UrlHelper

alias_method :link_to_original, :link_to

def permission?
true
end

def link_to(name, options = {}, html_options =
nil,*parameters_for_method_reference)
if permission?
link_to_original( name,
options,html_options,*parameters_for_method_reference )
end
end

end

the error message
howing app/views/users/_table.rhtml where line #40 raised:

stack level too deep

Extracted source (around line #40):

37:
38:


39: <%#{if $movtable.table.columns.$curr_key.sortable eq true}
40:
41: #
42: #{$movtable.table.columns.$curr_key.nome}
43: #

Trace of template inclusion: /app/views/users/list.rhtml

RAILS_ROOT: ./script/…/config/…
Application Trace | Framework Trace | Full Trace

#{RAILS_ROOT}/app/helpers/users_helper.rb:12:in link_to_original' #{RAILS_ROOT}/app/helpers/users_helper.rb:12:inlink_to_original’
#{RAILS_ROOT}/app/helpers/users_helper.rb:12:in link_to_original' #{RAILS_ROOT}/app/helpers/users_helper.rb:12:inlink_to_original’
#{RAILS_ROOT}/app/helpers/users_helper.rb:12:in `link_to_original’

… it repeat on an on

#{RAILS_ROOT}/app/helpers/users_helper.rb:12:in link_to' #{RAILS_ROOT}/app/helpers/movtable_helper.rb:121:insort_link’
#{RAILS_ROOT}/app/views/users/_table.rhtml:40
#{RAILS_ROOT}/app/views/users/_table.rhtml:36:in `each’
#{RAILS_ROOT}/app/views/users/_table.rhtml:36
#{RAILS_ROOT}/app/views/users/list.rhtml:9


#2

I think when you call link_to_original in the link_to method, it calls
the link_to method again because link_to_original is aliased to link_to.
Alias does not make a ‘copy’ of the original function. You’re just
creating another name for it.

Why do you not just use link_to_if or link_to_unless … the first
parameter is a condition. If it fails, the link just becomes limp and
harmless text.


#3

I try to use back the link_to that was generated by the scaffold, to
avoid modification of the rthml file.

so it there a way to improve my code so that it will work?


#4

I’ve had a similar problem. What you have to realize is that the
alias_method call isn’t like declaring something at the class level in a
java-type language. It’s a call to a class method, and it can occur
more than once.

Your alias_method call is getting called twice. the first time, it
aliases link_to_original to the standard link_to method, since you have
not yet overridden linkto. You then override link_to. So far so good.
However, when alias_method gets called the second time (for whatever
reason), it aliases link_to_original to the current def of link_to,
which is now your overridden version. When link_to_original
subsequently gets referenced in your new link_to, it points to your new
link_to, creating an infinite loop.

Why is your class def being parsed twice? I dunno.

To fix this, replace your alias_method with this

alias_method(:link_to_original, :link_to) unless
method_defined?(:link_to_original)

that should do the trick.

Hope that helps.


#5

alias_method is fact (essentially) does create a copy of the method.
See the following:

class Foo
def a
“a”
end
end

f = Foo.new

puts f.a #a

class Foo
alias_method :b, :a
end

puts f.a #a
puts f.b #a

class Foo
def a
“anew”
end
end

puts f.a #anew
puts f.b #a

aliasing b to point to a, then redefining a doesn’t make b points to the
new a. b still points to the original a method.


#6

Thanks. I was doing exactly the same thing and having exactly the same
issue. The only difference was I had original_link_to not
link_to_original.