Building an array of dates


#1

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…


#2

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


#3

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


#4

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.


#5

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 %>


#6

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…

<%= 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
%>


#7

On Sat, Dec 27, 2008 at 4:44 PM, Jeremy Weiskotten
removed_email_address@domain.invalid wrote:

start = Time.now.month
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


Robby R.
Chief Evangelist, Partner

PLANET ARGON, LLC
design // development // hosting w/Ruby on Rails


http://www.robbyonrails.com/
aim: planetargon

+1 503 445 2457
+1 877 55 ARGON [toll free]
+1 815 642 4068 [fax]