I am trying to create a dynamic menu using the following construct:
<%- menu_list = [ ‘first’, ‘second’, ‘third’] -%>
<%- menu_list.each do |m| -%>
<%= link_to "List All #{m.titlecase.pluralize} _path %>
<%- end -%>
What I cannot determine is what I have to do to replace so that the
link_to has a target. I have tried string substitution ("#{m}"_path)
but that gives a compile error:
_erbout.concat(( link_to “List All #{m.titlecase.pluralize}”,
("#{m}"_path) ).to_s); _erbout.concat "
I am sure that there must be a fairly straight forward way to do this.
Can someone point it out to me?
On May 1, 2008, at 20:58 , James B. wrote:
the
link_to has a target.
You can get it this way:
<%= link_to "List All #{m.titlecase.pluralize}", send("#{m}_path")
%>
Nevertheless in this case I tend to see repetition as a better option.
Compare the above to this crystal clear
<%= link_to "List All Firsts", first_path %>
<%= link_to "List All Seconds", second_path %>
<%= link_to "List All Thirds", third_path %>
If you have 35 of those then fine, but for a handful of them I find
copy & paste gives better code.
– fxn
Xavier N. wrote:
On May 1, 2008, at 20:58 , James B. wrote:
the
link_to has a target.
You can get it this way:
<%= link_to "List All #{m.titlecase.pluralize}", send("#{m}_path")
%>
Nevertheless in this case I tend to see repetition as a better option.
Compare the above to this crystal clear
<%= link_to "List All Firsts", first_path %>
<%= link_to "List All Seconds", second_path %>
<%= link_to "List All Thirds", third_path %>
If you have 35 of those then fine, but for a handful of them I find
copy & paste gives better code.
– fxn
Thank you.
My example was cut down to the essentials to avoid clutter and focus on
the my present issue. There are many related bits to each ‘m’ that have
a similar construction so that meta programming this represents a clear
advantage over cut and paste.
Now I have a related question. Some of these methods may or may not
have routes depending upon when and where they are invoked. So, I have a
guard conditional set up:
<%- role_list.each do |m| -%>
<%= "#{m.titlecase}" %>
<%= if defined? “#{m.pluralize}_path” then
link_to “List All #{m.titlecase.pluralize}”,
send("#{m.pluralize}_path")
else
nil
end %>
<%- end -%>
When the guard is explicit ( if defined? firsts_path then …) this
works. But I do not know how to test for a dynamically formed method
name. How is this done in Ruby?
2008/5/1 James B. [email protected]:
Now I have a related question. Some of these methods may or may not
have routes depending upon when and where they are invoked. So, I have a
guard conditional set up:
<%- role_list.each do |m| -%>
<%= "#{m.titlecase}" %>
<%= if defined? “#{m.pluralize}_path” then
When the guard is explicit ( if defined? firsts_path then …) this
works. But I do not know how to test for a dynamically formed method
name. How is this done in Ruby?
Yeah, defined? is not what you want in that case:
irb(main):001:0> defined? “foo”
=> “expression”
Use respond_to? instead.
Xavier N. wrote:
2008/5/1 James B. [email protected]:
Yeah, defined? is not what you want in that case:
irb(main):001:0> defined? “foo”
=> “expression”
Use respond_to? instead.
Works great using either idiom: Thanks!
<%- role_list.each do |m| -%>
- <%= "#{m.titlecase}" %>
<%= link_to "List All #{m.titlecase.pluralize}",
send("#{m.pluralize}_path") \
if respond_to? "#{m.pluralize}_path" %>
<%= if respond_to? "#{m.pluralize}_path" then
link_to "List All #{m.titlecase.pluralize}",
send("#{m.pluralize}_path")
else
nil
end %>
<%- end -%>
Can you explain to me the different behaviours between defined? and
respond_to? in this instance. I am not clear why defined? would work
with symbolized path names but not work with the same parameterized
string.to_sym.
Thanks again.
On Thu, May 1, 2008 at 11:54 PM, James B.
[email protected] wrote:
Can you explain to me the different behaviours between defined? and
respond_to? in this instance. I am not clear why defined? would work
with symbolized path names but not work with the same parameterized
string.to_sym.
respond_to? asks whether the object responds to some method. Since you
want to know whether self responds to the path generator that’s the
one.
defined? is more generic. That’s a special operator in the sense that
Ruby does not evaluate its argument. I don’t know the whole story
(anyone?) but a posteriori defined? works at parse time or something
like that to interpret the argument expression in a special way.
For example, if SOME_CONSTANT is unknown
defined? SOME_CONSTANT
does not raise NameError, it does not evaluate the argument. It
silently returns nil. If the constant was known it would return
“constant”.
Check this other one for example:
irb(main):004:0> a = “\n”
=> “\n”
irb(main):005:0> defined? a.chop!
=> “method”
irb(main):006:0> a
=> “\n”
You see? chop! is not being called, we are just told that a responds to
chop!.
I’d like to provide a better explanation of defined? but don’t have
Flanagan & Matz at hand.
Xavier N. wrote:
I’d like to provide a better explanation of defined? but don’t have
Flanagan & Matz at hand.
The main point that I see here is that when I am testing for the
existence of methods then I should use respond_to? and that is
sufficient.
On 1 May 2008, at 23:24, Xavier N. wrote:
want to know whether self responds to the path generator that’s the
one.
defined? is more generic. That’s a special operator in the sense that
Ruby does not evaluate its argument. I don’t know the whole story
(anyone?) but a posteriori defined? works at parse time or something
like that to interpret the argument expression in a special way.
defined? is a bit nuts:
http://redhanded.hobix.com/inspect/methodCheckDefined.html
I wrote too soon. I have another blank spot in my knowledge that need
filling.
This construct works:
<%- role_list.each do |m| -%>
-
<%= "#{m.titlecase}" if respond_to? "#{m.pluralize}_path" %>
<%= link_to "List All #{m.titlecase.pluralize}", \
send("#{m.pluralize}_path") if respond_to?
"#{m.pluralize}_path" %>
<%= link_to "Add New #{m.titlecase}", send("new_#{m}_path") \
if respond_to? "#{m.pluralize}_path" %>
<%- end -%>
and this does not:
<%- role_list.each do |m| -%>
-
<%= if respond_to? "#{m.pluralize}_path" then
"#{m.titlecase}"
link_to "List All #{m.titlecase.pluralize}",
send("#{m.pluralize}_path")
link_to "Add New #{m.titlecase}", send("new_#{m}_path")
end -%>
<%- end -%>
All I get in the html from this is the output of the last step in the if
block:
link_to “Add New #{m.titlecase}”, send(“new_#{m}_path”)
This indicate that I am only getting the final return value of a Ruby
method as the entire result of the if construct. This is not what I
intend or desire so is there some way of getting each step in the if
block to produce output onto the html page?
Xavier N. wrote:
if is an expression in Ruby, but the easy way to do that in ERb is
<% if … %>
this
that
<%= link_to … %>
<% end %>
Note the use of <% … %> instead of <%= … %>.
I tried that syntax first and could not get it to work. I have since
discovered why. I kept leaving the trailing -%> off of the “if”
statement. Sigh.
Thanks again.
On Fri, May 2, 2008 at 6:40 PM, James B.
[email protected] wrote:
send(“#{m.pluralize}path")
link_to “Add New #{m.titlecase}”, send("new#{m}_path”)
This indicate that I am only getting the final return value of a Ruby
method as the entire result of the if construct. This is not what I
intend or desire so is there some way of getting each step in the if
block to produce output onto the html page?
if is an expression in Ruby, but the easy way to do that in ERb is
<% if … %>
this
that
<%= link_to … %>
<% end %>
Note the use of <% … %> instead of <%= … %>.
Me again.
Now that I have this working in a view I want to move it all out into a
pair of methods that I can call from multiple views: role_list_head and
role_list_foot. Two questions arise from this:
Where do I put these methods? In application_helper.rb,
application_controller.rb, or somewhere else?
What does the method look like? Something akin to this I expect:
@role_list_default = [‘entity’, ‘client’, ‘employee’, ‘vendor’]
def role_list_head(list=@role_list_default)
link_to ‘Main Page’, :controller => ‘nav_menus’
list.each do |m|
# guard against missing path methods.
if respond_to? “#{m.pluralize}_path” then
link_to “List All #{m.titlecase.pluralize}”,
send("#{m.pluralize}path")
end
end
list.each do |m|
if respond_to? "new#{m.}path" then
link_to “Add New #{m.titlecase}”, send("new#{m}_path")
end
end
end
I know that this does not work, because I tried it. But something
somewhat like this has to be the answer.
On Fri, May 2, 2008 at 9:04 PM, James B.
[email protected] wrote:
What does the method look like? Something akin to this I expect:
@role_list_default = [‘entity’, ‘client’, ‘employee’, ‘vendor’]
This could be a constant.
end
somewhat like this has to be the answer.
That’s view stuff so should go to a helper or to a partial. The helper
would build and return a single string with HTML so that you can use
it like this
<%= role_list_header %>
On Fri, May 2, 2008 at 11:06 PM, James B.
[email protected] wrote:
That’s view stuff so should go to a helper or to a partial. The helper
would build and return a single string with HTML so that you can use
it like this
<%= role_list_header %>
yes, but which helper file exactly? All that I have read about helpers
indicates that they are tied to a specific controller by name. I tried
adding a dummy method to a file called lib/application_helper.rb but
when I called the method from a view I got a missing method error.
There are several options, but you can just throw it into
app/helpers/application_helper.rb. That file contains helpers that are
available everywhere.
Xavier N. wrote:
That’s view stuff so should go to a helper or to a partial. The helper
would build and return a single string with HTML so that you can use
it like this
<%= role_list_header %>
yes, but which helper file exactly? All that I have read about helpers
indicates that they are tied to a specific controller by name. I tried
adding a dummy method to a file called lib/application_helper.rb but
when I called the method from a view I got a missing method error.
James B. wrote:
I figured out what I was doing wrong in application_helper.rb. It really
helps if you put:
module ApplicationHelper
…
end
around your code. double sigh.
On Fri, May 2, 2008 at 11:17 PM, James B.
[email protected] wrote:
James B. wrote:
I figured out what I was doing wrong in application_helper.rb. It really
helps if you put:
module ApplicationHelper
…
end
around your code. double sigh.
Careful, you don’t need that file in lib, see the path in my previous
post.
On Sat, May 3, 2008 at 12:05 AM, James B.
[email protected] wrote:
Xavier N. wrote:
Careful, you don’t need that file in lib, see the path in my previous
post.
What are the implications of each. Why one place rather than the other?
Because app/helpers is the directory where helpers are expected to be
by convention. Note that application_helper.rb is generated there by
the rails command, and it already contains a module ApplicationHelper.