Forum: Ruby on Rails can't get date_select to work

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.
Fd1769776698da69ffd5bdda094d8581?d=identicon&s=25 Jon Evans (Guest)
on 2006-02-08 11:37
(Received via mailing list)
Hi,

I render a couple of date_select fields, the HTML looks fine, I can
see the values submitted back to the server, but AR doesn't pick them
up from the hash in Booking.new(params['booking']).

I've got a 'booking' object with parameters product, startdate and
enddate.

HTML snippets:
<select name="booking[startdate(1i)]">...
<select name="booking[startdate(2i)]">...
<select name="booking[startdate(3i)]">...

In the view controller method I create a booking object and set
startdate to Date.today+1, and enddate to Date.today+2.  When the
page renders the dates are showing correctly according to how the
controller set them up, so date_select is showing the right fields
from my model.

I've tried different browsers, and I've tried gem rails and edge rails.

 From the console log I can see the values:
Processing SiteController#booking (for 127.0.0.1 at 2006-02-08
10:19:25) [POST]
   Parameters: {"commit"=>"Check Availability", "action"=>"booking",
"id"=>"1",
     "controller"=>"site",
     "booking"=>{"startdate(1i)"=>"2006", "startdate(2i)"=>"2",
"startdate(3i)"=>"9",
     "enddate(1i)"=>"2006", "enddate(2i)"=>"2", "enddate(3i)"=>"10"}}


But the save always fails and the view reports the errors like so:

2 errors prohibited this booking from being saved
There were problems with the following fields:
     * Enddate can't be blank
     * Startdate can't be blank


The form looks like this:

<%=error_messages_for("booking")%>
<%=form_tag({:action => 'booking', :id=>@product})%>

<p><label for="booking_startdate">Start:</label><br/>
     <%=date_select("booking", "startdate")%>
</p>
<p><label for="booking_enddate">End:</label><br/>
     <%=date_select("booking", "enddate")%>
</p>
<%= submit_tag "Check Availability"%>
<%= end_form_tag %>

There are no methods in the model:

class Booking < ActiveRecord::Base
   belongs_to :product
   validates_presence_of :startdate, :enddate, :product
end

The controller method is quite simple:

   def booking
     @product = Product.find(params[:id])
     @booking = Booking.new(params['booking'])
     @booking.product = @product

     # I added these 3 lines so I could dump them
     # in the view to try and debug the problem:
     @startdate = params['booking']['startdate']
     @enddate = params['booking']['enddate']
     @params = params

     if @booking.save
       redirect_to(:action=>'index')
     else
       render(:action=>'view')
     end
   end

I dump @startdate, @enddate and @params in my view and get:
Startdate:
---
Enddate:
---
Params:
--- !map:HashWithIndifferentAccess
commit: Check Availability
action: booking
id: "1"
controller: site
booking: !map:HashWithIndifferentAccess
   startdate(1i): "2006"
   startdate(2i): "2"
   startdate(3i): "9"
   enddate(1i): "2006"
   enddate(2i): "2"
   enddate(3i): "10"


The database table has all the fields:

CREATE TABLE `bookings` (
   `id` int(11) NOT NULL auto_increment,
   `product_id` int(11) default NULL,
   `startdate` datetime default NULL,
   `enddate` datetime default NULL,
   `created_at` datetime default NULL,
   `updated_at` datetime default NULL,
   PRIMARY KEY  (`id`),
   KEY `bookings_product_id_index` (`product_id`),
   KEY `bookings_startdate_index` (`startdate`),
   KEY `bookings_enddate_index` (`enddate`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1


(they were originally 'date' fields, I changed them to 'datetime'
while trying to get this working).

Any help would be appreciated!

Jon
C1e5a9e9344b6d31b9df7303e6dc378a?d=identicon&s=25 Craig White (Guest)
on 2006-02-08 12:46
(Received via mailing list)
On Wed, 2006-02-08 at 10:36 +0000, Jon Evans wrote:
> <select name="booking[startdate(1i)]">...
>
>
> <%=error_messages_for("booking")%>
>
>      @product = Product.find(params[:id])
>        redirect_to(:action=>'index')
> Params:
>    enddate(2i): "2"
>    `created_at` datetime default NULL,
>
> Any help would be appreciated!
----
not an expert on this stuff at all - perhaps you have seen from my array
of confused questions but this looks to me like you need a definition
for the aggregation in the model to put this all back together.

I am using the following for names (which I learned from the Agile
book)...

class Wholename
  attr_reader :first_name, :middle_initial, :last_name

  def initialize(first_name, middle_initial, last_name)
    @first = first_name
    @initials = middle_initial
    @last = last_name
  end

  def to_s
    [ @first_name, @middle_initial, @last_name ].compact.join(" ")
  end
end

and then I can refer to either table.wholename or table.first_name,
table.last_name, etc. pretty much interchangeably.

In your case, I am not certain if you would need leading '0' on single
digit day/month but I think you can work that out.

Craig
Fd1769776698da69ffd5bdda094d8581?d=identicon&s=25 Jon Evans (Guest)
on 2006-02-08 23:34
(Received via mailing list)
Hi Craig,

On 8 Feb 2006, at 11:45, Craig White wrote:

> On Wed, 2006-02-08 at 10:36 +0000, Jon Evans wrote:
>>
>> I render a couple of date_select fields, the HTML looks fine, I can
>> see the values submitted back to the server, but AR doesn't pick them
>> up from the hash in Booking.new(params['booking']).
>

> not an expert on this stuff at all - perhaps you have seen from my
> array
> of confused questions but this looks to me like you need a definition
> for the aggregation in the model to put this all back together.

Thanks for your input, but I'm not convinced you're right.  All of
the other form field helpers produce fields which can be
automatically read back into the AR model object when the form is
submitted.  date_select works fine to read the date out of the model
object and render it, it's just that AR doesn't recognise the form
field when it is submitted, even though the data makes it back to the
server OK.

Anyone else?  Is Craig right, I have to handle the returned YYYY, MM
and DD fields myself?

I think I've decided that for the sake of a cleaner UI I'm going to
do my own dropdowns anyway.  One with a date, the other with a
combined month and year.  But it would still be useful to know where
I'm going wrong with date_select.

Thanks

Jon
C1e5a9e9344b6d31b9df7303e6dc378a?d=identicon&s=25 Craig White (Guest)
on 2006-02-09 00:31
(Received via mailing list)
On Wed, 2006-02-08 at 22:33 +0000, Jon Evans wrote:
>
> field when it is submitted, even though the data makes it back to the
> server OK.
>
> Anyone else?  Is Craig right, I have to handle the returned YYYY, MM
> and DD fields myself?
>
> I think I've decided that for the sake of a cleaner UI I'm going to
> do my own dropdowns anyway.  One with a date, the other with a
> combined month and year.  But it would still be useful to know where
> I'm going wrong with date_select.
----
now you've removed the context for which I gave an answer and with this
context, I would answer differently since I have used the date_select
function with nary a whimper and no extra futzing around.

You might find it wise to restate your question - perhaps now that you
have had more time to think about it and simplify it as best as you can
because that is the way you get answers. I know because when my normal
state of confusion is obvious in the question, no one is gonna answer
it.

Craig
Af93ba6b6b59f22a8f37e8de5702ef98?d=identicon&s=25 Bob Silva (Guest)
on 2006-02-09 00:36
(Received via mailing list)
If your model has a date or datetiime field, then AR should properly
convert
the multi-select values back into a valid date object for your database
when
you save your record. If it doesn't, then your database adapter doesn't
convert dates properly for your db or you are doing something else
wrong.
Giving it the wrong name maybe?

You'll need to provide more info of your table layout and how you are
calling the date_select for more help.

Bob
Fd1769776698da69ffd5bdda094d8581?d=identicon&s=25 Jon Evans (Guest)
on 2006-02-09 10:52
(Received via mailing list)
Hi Bob,

Thanks for your reply.

On 8 Feb 2006, at 23:36, Bob Silva wrote:

[I was asking whether AR was supposed to be able to automatically
parse the date fields generated by date_select when the form is
submitted.]

> You'll need to provide more info of your table layout and how you are
> calling the date_select for more help.


Well, my first message in this thread had all the information I
thought anyone might have needed to help, but as Craig has pointed
out it probably just made the problem appear to be more complicated. :-)

My table def is:
CREATE TABLE `bookings` (
   `id` int(11) NOT NULL auto_increment,
   `product_id` int(11) default NULL,
   `startdate` datetime default NULL,
   `enddate` datetime default NULL,
   `created_at` datetime default NULL,
   `updated_at` datetime default NULL,
   PRIMARY KEY  (`id`),
   KEY `bookings_product_id_index` (`product_id`),
   KEY `bookings_startdate_index` (`startdate`),
   KEY `bookings_enddate_index` (`enddate`)
) ENGINE=InnoDB DEFAULT CHARSET=latin1

startdate and enddate were originally of type 'date', I changed them
to 'datetime' because I thought that was the problem.

Here's the (simplified) form:
<%=form_tag({:action => 'booking', :id=>@product})%>
     <%= date_select( "booking", "startdate") %>
     <%= date_select( "booking", "enddate") %>
     <%= submit_tag "Check Availability"%>
<%= end_form_tag %>

To be clear, if I set startdate and enddate on @booking before
displaying the form, the values that I set are correctly displayed in
the drop-downs.  I think that proves that I haven't made a typo in
the parameter names or something basic like that.

The model is about as simple as it gets:
class Booking < ActiveRecord::Base
   belongs_to :product
   validates_presence_of :startdate, :enddate, :product
end

According to the log file the values get passed back to AR OK:
Processing SiteController#booking (for 127.0.0.1 at 2006-02-08
10:19:25) [POST]
   Parameters: {"commit"=>"Check Availability", "action"=>"booking",
"id"=>"1",
     "controller"=>"site",
     "booking"=>{"startdate(1i)"=>"2006", "startdate(2i)"=>"2",
"startdate(3i)"=>"9",
     "enddate(1i)"=>"2006", "enddate(2i)"=>"2", "enddate(3i)"=>"10"}}

error_messages_for("booking") produces:
2 errors prohibited this booking from being saved
There were problems with the following fields:
     * Enddate can't be blank
     * Startdate can't be blank

the controller method that the form gets submitted to is:
  def booking
     @product = Product.find(params[:id])
     @booking = Booking.new(params['booking'])
     @booking.product = @product

     if @booking.save
       redirect_to(:action=>'index')
     else
       render(:action=>'view')
     end
   end

I'm using a MySQL database on Mac OS X.

Thanks

Jon
F15fdc7cb2e911b3808837f2be244add?d=identicon&s=25 Adam Denenberg (Guest)
on 2006-02-09 15:25
(Received via mailing list)
FWIW i have to do something like this to get date_select back to a
usable form to be inserted into the DB

birthdate = @params[:user]["birthdate(1i)"] + '-' +
@params[:user]["birthdate(2i)"] + '-' +
@params[:user]["birthdate(3i)"]

@user = User.new
@user["birthdate"] = birthdate if birthdate

hope that helps.  I think i tried just doing @user
=User.new(@params[:user]) but the birthdate was breaking.

adam
This topic is locked and can not be replied to.