I have a calendar system in which the user enters date and time for an event in a seperate text_field. I store the date and time in 开发者_运维技巧one attribute (begin) in the Event model I have a hard time figuring out how to combine the date and time input and combine it into the begin attribute.
I preferably want to do this via a virtual attribute (:date
and :time
) so I can easily map my form against those virtual attributes without the need to do something in the controller.
Many thanks
You can make your own accessor methods for the date and time attributes like this:
def date
datetime.to_date
end
def date=(d)
original = datetime
self.datetime = DateTime.new(d.year, d.month, d.day,
original.hour, original.min, original.sec)
end
def time
datetime.to_time
end
def time=(t)
original = datetime
self.datetime = DateTime.new(original.year, original.month, original.day,
t.hour, t.min, t.sec)
end
You should use before_validation callback to combine data from two virtual attributes into one real attribute. For example, something like this:
before_validation(:on => :create) do
self.begin = date + time
end
Where date + time
will be your combining logic of the two values.
Then you should write some attr_accessor methods to get individual values if necessary. Which would do the split and return appropriate value.
I think you have a datetime field in your model, rails allows you to read in the date part and time part separately in your forms (easily) and then just as easily combine them into ONE date time field. This works specially if your attribute is a datetime.
# model post.rb
attr_accessible :published_on # just added here to show you that it's accessible
# form
<%= form_for(@post) do |f| %>
<%= f.date_select :published_on %>
<%= f.time_select :published_on, :ignore_date => true %>
<% end %>
The Date Select line will provide you the date part of published_on The Time Select line will provide you the time part of published_on. :ignore_date => true will ensure that the time select does not output 3 hidden fields related to published_at since you are already reading them in in the previous line.
On the server side, the date and time fields will be combined!
If you however you are reading the date as a text_box, then this solution doesnt work unfortunately. Since you are not using the composite attribute that rails provides for you built in on datetime.
In short, if you use date_select,time_select, rails makes it easy, otherwise you're free to look for other options.
You should use an open-source datetime picker widget that handles this for you, and not make the fields yourself as a text field.
精彩评论