Using helpers in rails 3 to output html
Solution 1
I agree with the comment above recommending the use of a partial... but if you DID need to do this in a helper, this is a cleaner way to implement:
def display_all(collection)
content_tag(:ul, class: "list") do
collection.collect do |member|
concat(content_tag(:li, id: member.name.gsub(' ', '-').downcase.strip) do
member.name
end)
end
end
end
I'd pass in a collection explicitly rather than passing in a symbol to create a collection so you aren't always required to display ALL the records in a particular table at once. You could add pagination, etc.
Solution 2
@Joe,
You can still use your method display_all(collection_sym)
Just use:
return html.html_safe
instead of:
return html
I still find that in many situations, it is better to generate HTML from helpers, instead of using partials. So the html_safe
function in Rails 3 will make sure that you generate HTML, instead of converting it to String
.
Solution 3
As @TheDelChop says, you need a concat
for the inner content_tag
, otherwise the output is just <ul></ul>
Here's what that looks like:
def display_all(collection)
content_tag(:ul, :class => "list") do
collection.collect do |member|
concat(
content_tag(:li, :id => member.name.gsub(' ', '-').downcase.strip) do
member.name
end
)
end
end
end
More explanation here: Nesting content_tag in Rails 3
TheDelChop
I am the lead developer of RentingSmart.com, a great way to manage all of your property needs! I enjoy hacking on Ruby, C++ and Javascript, with a lot of interest in crafting clean code in the tradition of Uncle Bob Martin. Tools I'm using right now: Ruby on Rails Redis Postgresql Coffeescript Ember.js
Updated on July 09, 2022Comments
-
TheDelChop almost 2 years
I'm trying my best to build a helper that outputs a <'ul> consisting of all the members of a collection. For each member of the collection I want to print out a <'li> that has a title, and a div of links to CRUD the member. This is pretty similar to what Rails outputs for scaffolding for the index view.
Here is the helper I've got:
def display_all(collection_sym) collection = collection_sym.to_s.capitalize.singularize.constantize.all name = collection_sym.to_s.downcase html = '' html << "<ul class=\"#{name}-list\">" for member in collection do html << content_tag(:li, :id => member.title.gsub(' ', '-').downcase.strip) do concat content_tag(:h1, member.title, :class => "#{name}-title") concat link_to 'Edit', "/#{name}/#{member.id}/edit" concat "\|" concat link_to 'View', "/#{name}/#{member.id}" concat "\|" concat button_to 'Delete', "/#{name}/#{member.id}", :confirm => 'Are you sure? This cannot be undone.', :method => :delete end end html << '</ul>' return html end
And that output exactly what I want. First of all, if anybody thinks there's a better way to do this, please feel free to correct me, I suspect that I'm doing this in a bass ackwards way, but at the moment its the only way I know how.
I then attempted to wrap the links in a div as follows:
def display_all(collection_sym) collection = collection_sym.to_s.capitalize.singularize.constantize.all name = collection_sym.to_s.downcase html = '' html << "<ul class=\"#{name}-list\">" for member in collection do html << content_tag(:li, :id => member.title.gsub(' ', '-').downcase.strip) do concat content_tag(:h1, member.title, :class => "#{name}-title") concat content_tag(:div, :class => "links-bar") do concat link_to 'Edit', "/#{name}/#{member.id}/edit" concat "\|" concat link_to 'View', "/#{name}/#{member.id}" concat "\|" concat button_to 'Delete', "/#{name}/#{member.id}", :confirm => 'Are you sure? This cannot be undone.', :method => :delete end end end html << '</ul>' return html end
However, I now no longer get any of the markup inside the div.links-bar output to the view. I'm sure this must have something to do with block and bindings, but I can for the life of me figure out what or how to go about fixing it. Can anybody offer any help?