building an array of dates

I need to build an array that contains lots of date objects.

I've got a booking model and it contains stuff like this...

  create_table "bookings", :force => true do |t|
    t.string "firstname"
    t.string "lastname"
    t.integer "number_of_people"
    t.integer "deposit"
    t.integer "price"
    t.integer "days"
    t.datetime "from"
    t.datetime "to"
    t.datetime "created_at"
    t.datetime "updated_at"
  end

SOO - each booking starts on a date and finishes on a date...

I need to collect up all the booking dates in an array so that I can do
stuff with them...

I figure i need a method in my model to do it...

something like

  def self.all_booking_dates

    find(:all); # first off find all the booking records

    @BookedDays = ( XXX ).map # do something here to create an array
with all the dates in, maybe I need a loop ... sorry bit stuck?

  end

be grateful for any tips.

thanks...

bingo bob wrote:

I need to collect up all the booking dates in an array so that I can do
stuff with them...

I figure i need a method in my model to do it...

something like

  def self.all_booking_dates

    find(:all); # first off find all the booking records

    @BookedDays = ( XXX ).map # do something here to create an array
with all the dates in, maybe I need a loop ... sorry bit stuck?

  end

To get an array of dates for just one booking, you can build a range and
then convert it to an array:

(from..to).to_a

To get the array of dates for a set of bookings (such as all bookings),
I think something like this is what you're looking for:

bookings.map { |b| (b.from..b.to).to_a }.flatten.uniq.sort

Thanks, I'll try that.

I got to here myself, but it's not right ! I think it's close though and
I find this syntax easier to read.

def availability

  @bookings = Booking.find(:all)

  for booking in @bookings do
    bookingfirstday = booking.from.to_date
    bookinglastday = booking.to.to_date
    @BookedDays = (bookingfirstday..bookinglastday).map
  end

end

Can you explain why it's wrong ?

The result is that I @BookedDays only gets set to the last evaluated
booking (I think).

I will try your way though, thanks. (I'd like to get my way working also
if poss)?

Is the loop rewriting @BookedDays each time around rather than adding to
it?

ta

bingo bob wrote:

Thanks, I'll try that.

I got to here myself, but it's not right ! I think it's close though and
I find this syntax easier to read.

def availability

  @bookings = Booking.find(:all)

  for booking in @bookings do
    bookingfirstday = booking.from.to_date
    bookinglastday = booking.to.to_date
    @BookedDays = (bookingfirstday..bookinglastday).map
  end

end

Can you explain why it's wrong ?

The result is that I @BookedDays only gets set to the last evaluated
booking (I think).

I will try your way though, thanks. (I'd like to get my way working also
if poss)?

Is the loop rewriting @BookedDays each time around rather than adding to
it?

ta

There are a couple problems. The first is that, yes, @BookedDays is
being rewritten, not appended to. You need to initialize the array
before the loop starts (@BookedDays = []) and use the += method to
append to it. Also, you should renamed that variable to @booked_days.
You can do this with a for-loop, but I suggest getting used to the
closured-oriented methods in Enumerable and Array. Your code will be
much more concise and expressive.

Thanks that's very clear and helpful, I'll try and use the more concise
method.

It's working for me and I understand why my version wasn't.

Maybe my brain is squished but I've done the hard thing and now this
next more simple loop is causing me problems in my view. I wish to show
12 calendars from the current month to 12 months on.

So I know how to display one....<working>

<%= calendar(:year => 2009, :month => 1) do |d|

    if @BookedDays.include?(d)
      [d.mday, {:class => "specialDay"}]
    else
      [d.mday, {:class => "normalDay"}]
    end

end

%>

How do I display twelve of em...I know this is uber easy but I can't get
it to work.

I firgure something like what follows is useful but I cant get the loop
within the loop working in the view.

<%
start = Time.now.month
finish = Time.now.month + 12
%>

bingo bob wrote:

How do I display twelve of em...I know this is uber easy but I can't get
it to work.

I firgure something like what follows is useful but I cant get the loop
within the loop working in the view.

<%
start = Time.now.month
finish = Time.now.month + 12
%>

Yeah, that's not going to work. The easiest way is probably something
like this:

<% d = Date.today %>
<% 12.times do %>

  <%= calendar(:year => d.year, :month => d.month) do |d|
    if @BookedDays.include?(d)
      [d.mday, {:class => "specialDay"}]
    else
      [d.mday, {:class => "normalDay"}]
    end
  end
  %>

<% d >>= 1 # advance 1 month %>
<% end %>

Small critique here on your code style. @BookedDays doesn't really
follow Ruby on Rails conventions. Camel-case should only be used by
class/module definitions and references. @booked_days is the
convention that Rails encourages.

This might be something that you've decided based on a personal or
team preference, but in case you're not attached to it, following
Rails conventions will make your life and anybody else that later
works on a project.. a little easier. :slight_smile:

Cheers,
Robby