tags:

views:

249

answers:

4

I am defining monday and friday using the following:

@monday = Date.today.at_beginning_of_week

@friday = 5.days.since(@monday)

But I actually need, for any given day, to loop through Monday, Tuesday, Wednesday and take that date and put the output into a column.

<th>Monday</th>
<th>Tuesday</th>
etcetera

A given row, for example, would be:

<tr><td>method_with_arg(monday)</td><td>method_with_arg(tuesday)</td><td>method_with_arg(wednesday)</td></tr>

This is where value is a method that takes args date.

What's the cleanest way to do this?

Thanks.

+3  A: 
def dates_week(d)
  (d.beginning_of_week...d.beginning_of_week+5).map{|a|
    "<td>#{a.strftime('%F')}</td>"
  }.join
end

dates_week Date.today
#=> "<td>2010-05-17</td><td>2010-05-18</td><td>2010-05-19</td><td>2010-05-20</td><td>2010-05-21</td>"

Instead of a.strftime you can call any other method receiving Date and returning string, such as mails_sent_on(a) etc. You can also use yield a there to pass your date-dependent logic using block:

def dates_week(d)
  (d.beginning_of_week...d.beginning_of_week+5).map{|a|
    yield a
  }.join
end

dates_week(Date.today) { |d|
  "<td>#{mails_sent_on(d)}</td>"
}

or, keeping strings out of dates_week method:

def dates_week(d)
  (d.beginning_of_week...d.beginning_of_week+5).map{|a|
    yield a
  }
end

dates_week(Date.today) { |d|
  mails_sent_on(d)
}.join(', ')

or whatever form you need.

Mladen Jablanović
I need to pass the actual value of the date into another method to output values for the other rows, such as emails sent, calls made, contacts added, etcetera...how can I set the output to be a variable I can plug in as an argument?
Angela
In addition to my concerns about non-DRY-ness, I think you need a bracket around `d.beginning_of_week+5` (Been there, done that)
Andrew Grimm
@Angela: I'm not sure I understand you. @Andrew: No need for parenthesis there, at least in Ruby 1.9. Tried your example as well, works the same with or without the parens.
Mladen Jablanović
@Mladen -- I guess what I mean is I need to pass an actual date (I think) not a string into another method for each row of the table (for example, show all the emails sent on that day)....would the format be sent_emails(a)?
Angela
@Angela: I updated the answer, hopefully it will be helpful.
Mladen Jablanović
+1  A: 

I just use Plain Old Ruby Objects, but I think if you want to keep things DRY, you'd want to separate out the logic of weekdays from what you're using the weekdays for.

def dates_week(d)
  d.beginning_of_week...(d.beginning_of_week+5)
end

dates_week(Date.today).map {|a|
  "<td>#{a.strftime('%F')}</td>"
}.join
Andrew Grimm
+1  A: 

I'd go even one step further than Andrew and have it take a block:

def dates_week(d, delim)
  "<tr>" + (d.beginning_of_week...(d.beginning_of_week+5)).map do |day|
    "<#{delim}> #{yield(day)} </#{delim}>"
  end.join + "</tr>"
end

dates_week(Date.today, "th") {|d| d.strftime("%A")} # => <tr><th>Monday</th><th>Tuesday</th>...
dates_week(Date.today, "td") {|d| some_function(d)} #first row
Isaac Cambron
okay going to go with this -- but now I can't find all the emails sent on the passed-in argument because the emails use a date-timestamp.... :\
Angela
You should be able to find() them such that day < time < day + 1
Isaac Cambron
A: 

The simplest solution I could think of would be:

monday = Date.today.at_beginning_of_week
days = []
7.times do |x|
     days << x.days.since(@monday)
end

days.each do |day|
     puts "<td>" + func(day) + "</td>"
end

That should do the trick

thomasfedb
This seems simple...but all of that would need to take place in the view or it would be in the dates_week()
Angela
I would define a helper method.
thomasfedb