我正在使用日期时间在日历中保存一些约会。 通过这种方式,我可以存储togheter日期和时间,而不会将这两个值区分开来。
我想要的是允许用户编辑约会和更改日期/时间。 事实是我不能让用户自由选择任何小时,但任何约会必须在预定的小时范围内设置(24小时格式:10,12,14,16,18,20)。
由于在文档中我找不到任何方法来自定义datetime_select
我实际上使用以下表单:
.control-group
= f.label :start_at, :class => 'control-label'
.controls
= f.date_select :start_at, :value => f.object.start_at, :class => "datetimefield"
.control-group
= f.label :start_at, :class => 'control-label'
.controls
= f.select :start_at, :value => Event::ALLOWED_HOURS, :class => 'number_field'
Event::ALLOWED_HOURS
是一个数组,其中包含我想让用户选择的小时数。
提交此表单时,更新操作会丢失时间信息,从而导致日期时间如下:2012-05-18 00:00:00
而不是使用我选择中定义的小时。
我可以做些什么来使我的工作成为可能?
这是控制器,请注意这是EventCalendar
的嵌套资源:
class EventsController < ApplicationController
before_filter :authenticate_user!
load_and_authorize_resource
# GET /events
# GET /events.json
def index
respond_to do |format|
format.html # index.html.erb
format.json { render json: @events }
end
end
# GET /events/1
# GET /events/1.json
def show
@event_calendar = EventCalendar.find(params[:event_calendar_id])
respond_to do |format|
format.html # show.html.erb
format.json { render json: @event }
end
end
# GET /events/new
# GET /events/new.json
def new
@event_calendar = EventCalendar.find(params[:event_calendar_id])
@start_at = Time.parse("#{params[:day]} #{params[:hour]}")
respond_to do |format|
format.html # new.html.erb
format.json { render json: @event }
end
end
# GET /events/1/edit
def edit
@event_calendar = EventCalendar.find(params[:event_calendar_id])
end
# POST /events
# POST /events.json
def create
@event_calendar = EventCalendar.find(params[:event_calendar_id])
@start_at = params[:start_at]
respond_to do |format|
if @event.save
format.html { redirect_to root_path, notice: 'Appuntamento creato con successo.' }
format.json { render json: @event = EventCalendar.find(params[:event_calendar_id]), status: :created, location: @event }
else
format.html { render action: "new" }
format.json { render json: @event.errors, status: :unprocessable_entity }
end
end
end
# PUT /events/1
# PUT /events/1.json
def update
@event_calendar = EventCalendar.find(params[:event_calendar_id])
respond_to do |format|
if @event.update_attributes(params[:event])
format.html { redirect_to root_path, notice: 'Appuntamento aggiornato con successo.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: @event.errors, status: :unprocessable_entity }
end
end
end
# DELETE /events/1
# DELETE /events/1.json
def destroy
@event_calendar = EventCalendar.find(params[:event_calendar_id])
@event.destroy
respond_to do |format|
format.html { redirect_to root_url, notice: 'Appuntamento cancellato con successo.'}
format.json { head :no_content }
end
end
end
答案 0 :(得分:2)
根据David的建议,我会创建一个虚拟属性start_at_hours
,然后只需编辑定义Event
回调的模型before_update
,而不是将该行放在控制器中:
# inside your model
before_update :set_hour
def start_at_hours
if !self.start_at.blank?
self.start_at.hour
end
end
def start_at_hours=(value)
end
# model code ...
private
def set_hour
self.start_at = Time.parse(self.start_at.to_s) + self.start_at_hours.to_i.hours
end
这应该按照您的需要无异常地工作。 它与David解释相同,但直接在模型中无需更改控制器。
编辑:通过定义一个getter和一个setter你也可以设置你的select的默认值(在这种情况下不需要setter,但我还是把它放了。)
答案 1 :(得分:0)
问题在于:创建@start_at
变量时,您的创建(和更新)方法不会查看小时字段。尝试以下,它应该工作:
.control-group
= f.label :start_at, :class => 'control-label'
.controls
= f.date_select :start_at, :value => f.object.start_at, :class => "datetimefield"
.control-group
= f.label :start_at, :class => 'control-label'
.controls
= f.select "start_at_hours", :value => Event::ALLOWED_HOURS, :class => 'number_field'
在控制器的更新方法中:
# PUT /events/1
# PUT /events/1.json
def update
@event_calendar = EventCalendar.find(params[:event_calendar_id])
respond_to do |format|
params[:start_at] = Time.parse(params[:start_at]) + params[:start_at_hours].to_i.hours
if @event.update_attributes(params[:event])
format.html { redirect_to root_path, notice: 'Appuntamento aggiornato con successo.' }
format.json { head :no_content }
else
format.html { render action: "edit" }
format.json { render json: @event.errors, status: :unprocessable_entity }
end
end
end
关键是这一行:
params[:start_at] = Time.parse(params[:start_at]) + params[:start_at_hours].to_i.hours
它正在用一个包含额外小时的新Time对象替换start_at
param(只包含日期)。