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