0

カレンダーにいくつかの予定を保存するために日時を使用しています。このようにして、2つの値を区別せずに、日付と時刻を一緒に保存できます。

私が欲しいのは、ユーザーが予定を編集したり、日付/時刻を変更したりできるようにすることです。実際、ユーザーが自由に時間を選択できるようにすることはできませんが、予定は事前定義された時間範囲(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
4

2 に答える 2

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の説明と同じことを行いますが、コントローラーを変更することなく、モデル内で直接実行します。

編集:ゲッターとセッターを定義することで、選択のデフォルト値を設定することもできます(この場合、セッターは必要ありませんが、とにかく設定します)。

于 2012-05-18T14:31:54.073 に答える
0

問題は次のとおりです。create(およびupdate)メソッドは、@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

start_atこれは、パラメータ(日付のみを含む)を、余分な時間が含まれている新しいTimeオブジェクトに置き換えています。

于 2012-05-18T14:01:55.823 に答える