How to override a mixin method, but then call the overridden

Hi,

Can anyone recommend how to override a mixin method but then call the
overridden method within this??? (e.g. like calling “super”)

Specifically I would like to provide an overridden “link_to” method to
my
views which would add a params[:locale] parameter to the mix and THEN
call
the original/rails “link_to” method after this. Like a “super” type
call.

Any suggestions on how to do this sort of overridding/overloading with
mixin
methods?

Thanks

Greg H. wrote:

Can anyone recommend how to override a mixin method but then call the
overridden method within this??? (e.g. like calling “super”)

Specifically I would like to provide an overridden “link_to” method to
my views which would add a params[:locale] parameter to the mix and THEN
call the original/rails “link_to” method after this. Like a “super”
type call.

Any suggestions on how to do this sort of overridding/overloading with
mixin methods?

To have access to the original link_to as link_to_orig, put this in your
helper module:

def self.append_features(base)
base.class_eval ‘alias :link_to_orig :link_to’
super
end


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

excellent - thanks

Is there any good tutorial on advanced use of Ruby to perform these
types of
tweaks that are available? e.g. other key ruby methods that help in
injecting/overriding methods etc?

Anyone pick why this modified version of “url_for” doesn’t seem to be
picked
up by a “url_for” in one of my views? (i.e. it still seems to use the
original rails version)

============== application_helper.rb ===============
module ApplicationHelper

def self.included(base)
base.class_eval do
alias_method :link_to_old, :link_to unless
method_defined?(:link_to_old)
alias_method :link_to, :link_to_new
end
end

def link_to_new
return “link_to_newTEXT”
end

end

thanks Mark,

So this is basically what I had in the previous post (which wasn’t
working)
but adds the “base.extend(ClassMethods)”?

So my take of this is I hadn’t allowed the ClassMethods to be extended
then,
and that’s why it wasn’t working???

Mark Reginald J. :

Any suggestions on how to do this sort of overridding/overloading with
mixin methods?

To have access to the original link_to as link_to_orig, put this in your
helper module:

def self.append_features(base)
base.class_eval ‘alias :link_to_orig :link_to’
super
end

Hi Mark and Greg,

I think it should work with alias_method_chain :
http://weblog.rubyonrails.com/2006/4/26/new-in-rails-module-alias_method_chain

alias_method_chain :link_to, :locale
so you can access to link_to_without_locale

best,

-- Jean-François.


Ã? la renverse.

Can anyone help here? The following is still not working. Again I’m
trying
to override for my views the “link_to” method, but within my version I
still
need to call the real rails “link_to” version at the end.

The problem with the code below is it never actually triggers the views
to
use a different version of “link_to”.

Suggestions?

======= application_helper.rb ===================
module ApplicationHelper

def self.included(base)
base.extend(ClassMethods)
base.class_eval do
alias_method :link_to_old, :link_to unless
method_defined?(:link_to_old)
alias_method :link_to, :link_to_new
end
end

def link_to_new (*args)
link_to “test text” <==== THIS NEVER GETS CALLED
end

end
======= application_helper.rb ===================

Thanks in advance

oh oh - just tried this Mark and this doesn’t work in fact…something
to do
with using this technique within application_helper.rb and access the
updated method (link_to) from a view??

bump (just really keen to understand this stuff & where I’m going wrong
if
someone knows)

Greg H. wrote:

module ApplicationHelper
def link_to_new (*args)
link_to “test text” <==== THIS NEVER GETS CALLED
end

end

Yes, it looks like this sort of technique won’t work with helpers
because Rails first includes all the relevant application helper
modules into an anonymous master helper module, before including
that in the controller and view template classes (in which the
Rails helpers have already been included). So the alias has to be
delayed by one include step. Is there any nice way to do this
other than trying to push into the master module its own
included/append_features method?

As for the details of what the above code is doing: You only
need the “base.extend(ClassMethods)” if you want to define
class methods on the target class or module, not usually needed
for controllers and views. And append_features is called before
the module methods are included, so you can name your method
link_to and simply alias the old one. The included method is
called after the module’s methods are included, so you need
two aliases.


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