How can I refactor the following code? I know that the code from the
Ruby for Rails book was meant to illustrate some concepts. I am just
curious to know how I can utilize the dynamic capabilities of Ruby. TIA.
Then, the link_to_composer method would look like this:
def link_to_composer(composer)
link_to_item(composer, :whole_name)
end
I don’t think spreading that knowledge (the field name to show for
particular model) is a good idea. It almost eliminates the advantage of
using custom link helpers and error prone.
I don’t think spreading that knowledge (the field name to show for
particular model) is a good idea. It almost eliminates the advantage of
using custom link helpers and error prone.
Ahh… sorry. Missed the second part.
Yeah, that kind of generalization is a good thing. Although, I would
made it
more flexible:
This will allowading extra params to url_for and overriding default
ones.
You could even add html_options as fourth param or use technique as in
link_to_remote (where url params go to options[:url], html params -
options[:html] etc)
link_to edition.description,
end
:controller => “instrument”,
:action => “show”,
:id => instrument.id
end
First, make a method in each of those models called ‘title_for_links’,
which returns the appropriate bit of text. That’ll standardise all of
those different method calls.
Could “named routes” be an easier way to do it? Also if you stick with
your current method what about using “define_method” to do some
meta-programming. So you can turn your code into:
I don’t think spreading that knowledge (the field name to show for
particular model) is a good idea. It almost eliminates the advantage of
using custom link helpers and error prone.
It’s not really spreading the knowledge; the starting point is
presumably:
link_to @composer.whole_name …
link_to @edition.nice_title
and so on. I think it’s reasonable to abstract whatever is the same
between these different cases, and parameterize whatever isn’t.
:action => “show”,
It depends on how nuts you want to go. This code should create a
class Foo
%w(composer edition edition_title work instrument).each do |thingie|
src = <<-END_SRC
def link_to_#{thingie}(link_text, #{thingie})
You don’t have to use thingie as the local variable in the method
(although I did so in the written-out versions, to match the
ActiveRecord class names); you can use any variable name, and then
reuse it in the :id line below.
%w(composer edition edition_title work instrument).each do |thingie|
define_method("link_to_#{thingie}") do |link_text,obj|
link_to(link_text,
:controller => thingie,
:action => "show",
:id => obj[:id])
end
end
It depends on how nuts you want to go. This code should create a
bunch of link_to methods that take a link_text and object argument
(different from yours which only appears to take an object argument).
I’ve defined a stub link_to method and some added a few lines of code
to see if this really works. Let me know if this helps answer the
question.
BTW: Another way to solve the problem is create the method using
method_missing, although you have to be careful because Rails relies
on this to some extent for its magic.
class Foo
%w(composer edition edition_title work instrument).each do |thingie|
src = <<-END_SRC
def link_to_#{thingie}(link_text, #{thingie})
self.link_to(link_text,
:controller => “#{thingie}”,
:action => “show”,
:id => #{thingie}[:id])
end
END_SRC
class_eval src, FILE, LINE
end
def link_to(text, options = {})
puts “link text is [#{text}] and link variables are:”
options.each_pair{|option, value| puts “#{option}: #{value}”}
end
end