sebkkom
sebkkom

Reputation: 1446

Quite new rails developer confused over content_tag and helpers

I am trying to create a calendar table to display the daily availability of every staff member of a company. What I think I need is a header with the days of the month and then a row (with as many cells as the number of the days) for each staff member. The different background color of each cell will represent a different availability status and the staff members change so I want all this to be dynamically generated.

After researching online and with Ryan Bates' Railscast #213 (Calendars Revised) as my guide, I have so far managed to generate the header of my table that displays the days of the month in each cell.

And that's my code so far:

module ReceptionHelper
def reception(date = Date.today, &block)
    Reception.new(self, date, block).table
end

class Reception < Struct.new(:view, :date, :callback)
    delegate :content_tag, to: :view

    def table
        content_tag :table, class: "calendar" do
            daysHeader
        end
    end

    def daysHeader
        last_day = date.end_of_month.strftime("%d").to_i
        (0..last_day).to_a.map { |day| content_tag :th, day }.join.html_safe
    end
end

Now, here is where the questions and confusion begins:

As you understand, I am quite lost in this and it seems I am not even clearly getting why the part that works as I want it to is correct. I hope this post doesn't give the impression that I am looking to have everything served to me in a dish - I am rather looking for directions that will help me understand. :)

EDIT:

I've made some progress by changing the staffRows method to this:

def staffRows
    staff.to_a.in_groups_of(1).map do |staff|
        content_tag :tr do
            staff.map { |room| content_tag :th, staff.name }.join.html_safe
        end
    end.join.html_safe
end

However this produces only one cell for each room while I want a row with as many cells as the header.

Upvotes: 1

Views: 1736

Answers (1)

Andrius Chamentauskas
Andrius Chamentauskas

Reputation: 756

First of all ruby conventions: use 2 spaces for spacing and use _ for method names.

Now meet your best friend when writing complex helpers: concat. What it does is outputs string directly to ERB buffer. To show you and example:

def my_helper
  concat "hello world"
end
<% my_helper %>

would output hello world in html even though we used <% and not <%=.

It's very important method when dealing with blocks in helpers, as it means you can call concat multiple times in block and both strings will be output. Here's an example:

def my_helper
  content_tag :div do
    concat "Hello "
    concat "World"
    concat "!"
  end
end
<%= my_helper %>

would output <div>Hello World!</div>. So using same idea you could do something like this:

def my_helper
  content_tag :ul do
    @people.each do |person|
      concat content_tag(:li, person.name)
    end
  end
end
<%= my_helper %>

which would result in something like this: <ul><li>John Doe</li><li>Mike Tyson</li></ul>.

So I would rewrite days_helper to something like this:

def days_header
  (0..date.end_of_month.day).each { |day| concat content_tag(:th, day) }
end

do something similar with staff_rows method and then table method would look simply like this:

content_tag :table, class: "calendar" do
  days_header
  staff_rows
end

As for the callback part of question: &block captures block that is passed to method into Proc object. This object can later be passed around to other methods or called directly. As you're not using callback object I would simply advise to remove it.

Upvotes: 6

Related Questions