How to put logic into Rails helper?
I have a view where I am trying to check if a field in a table is present, and if so, print just that field. If not, it should print the text: "(none)". In my view I have:
<%= list_fields(feed) %>
And in my helper file I have:
def list_fields(feed)
feed.xml_fields.each do |field|
if field.tags?
field.tags
else
puts "(none)"
end
end
end
Right now this displays the entire table row for each field object if it has tags, and "[]" if it has no tags. I just want the individual tags entry to display or "(none)". W开发者_开发知识库hat am I missing in my helper?
You have two problems. The first one is that your helper does not return the value which could be included in the view by the <%= ... %>
construct.
The .each
call returns the object on which it has been called, in this case it would be feed.xml_fields
, and it does NOT return the individual values calculated by the block.
The second problem is that puts
in Rails does not place the text in the rendered view - it is not PHP.
I am not very confident what exact output you expect, but if you want to return the first 'field' which has 'tags', then you can do this:
def list_fields(feed)
f = feed.xml_fields.detect {|field| field.tags? }
f ? f.tags : "(none)"
end
If you want to list all the tags, and to return the string "(none)", if there are no tags, then use something like this:
def list_fields(feed)
f = feed.xml_fields.select {|field| field.tags? }.map {|field| field.tags }
f.empty? ? "(none)" : f.join(", ")
end
If you want to join the fields with some HTML markup, like a <br/>
, then use this:
def list_fields(feed)
f = feed.xml_fields.select {|field| field.tags? }.map {|field| h(field.tags) }
f.empty? ? "(none)" : f.join("<br/>").html_safe
end
Note that there are two changes: the individual tags
values are escaped by the h
function, and then the joined string is marked as being already sanitized. In this case the view will not escape the string again.
If you really want to use something like puts
in views or helpers, then you may read about the method concat.
You should change your function in such a way:
def list_fields(feed)
feed.xml_fields.each do |field|
if field.tags?
return field.tags
else
return "(none)"
end
end
end
There are 2 changes:
- No put in the helper
- return from the loop. The result of an
each
-loop is the array itself, so at the end, it will be returned in your version anyway.
I do not understand why you do the loop.
Return strings from your helper, instead of using puts
. I don't know what format field.tags
is, but my guess is it's an array. Format the string how you want it and just return it from the helper.
Something like:
def list_fields(feed)
feed.xml_fields.each do |field|
if field.tags?
"some string"
else
"(none)"
end
end
end
精彩评论