Forum: Ruby on Rails building an array of dates

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
bingo b. (Guest)
on 2008-12-27 16:23
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...
Jeremy W. (Guest)
on 2008-12-27 18:11
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
bingo b. (Guest)
on 2008-12-27 18:28
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
Jeremy W. (Guest)
on 2008-12-27 18:37
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.
bingo b. (Guest)
on 2008-12-27 19:08
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
%>
Jeremy W. (Guest)
on 2008-12-28 02:44
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 %>
Robby R. (Guest)
on 2008-12-28 18:48
(Received via mailing list)
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. :-)

Cheers,
Robby

--
Robby R.
Chief Evangelist, Partner

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

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

+1 503 445 2457
+1 877 55 ARGON [toll free]
+1 815 642 4068 [fax]
This topic is locked and can not be replied to.