私は以下にアプローチするためのRails-yの方法を探しています:
Eventモデルの2 つのdatetime
属性:
start_at: datetime
end_at: datetime
フォームでそれらにアクセスするために 3 つのフィールドを使用したいと思います。
event_date
start_time
end_time
私が抱えている問題は、実際の属性とstart_at
仮想属性を「同期」状態に保ち、フォームを介して、および/または&を介して直接モデルを更新できるようにする方法end_at
です。
class Event < ActiveRecord::Base
attr_accessible :end_at, :start_at, :start_time, :end_time, :event_date
attr_accessor :start_time, :end_time, :event_date
after_initialize :get_datetimes # convert db format into accessors
before_validation :set_datetimes # convert accessors into db format
def get_datetimes
if start_at && end_at
self.event_date ||= start_at.to_date.to_s(:db) # yyyy-mm-dd
self.start_time ||= "#{'%02d' % start_at.hour}:#{'%02d' % start_at.min}"
self.end_time ||= "#{'%02d' % end_at.hour}:#{'%02d' % end_at.min}"
end
end
def set_datetimes
self.start_at = "#{event_date} #{start_time}:00"
self.end_at = "#{event_date} #{end_time}:00"
end
end
どちらが機能しますか:
1.9.3p194 :004 > e = Event.create(event_date: "2012-08-29", start_time: "18:00", end_time: "21:00")
=> #<Event id: 3, start_at: "2012-08-30 01:00:00", end_at: "2012-08-30 04:00:00", created_at: "2012-08-22 19:51:53", updated_at: "2012-08-22 19:51:53">
実際の属性を直接設定するまで (検証時にend_at
戻す):end_time
1.9.3p194 :006 > e.end_at = "2012-08-30 06:00:00 UTC +00:00"
=> "2012-08-30 06:00:00 UTC +00:00"
1.9.3p194 :007 > e
=> #<Event id: 3, start_at: "2012-08-30 01:00:00", end_at: "2012-08-30 06:00:00", created_at: "2012-08-22 19:51:53", updated_at: "2012-08-22 19:51:53">
1.9.3p194 :008 > e.save
(0.1ms) BEGIN
(0.4ms) UPDATE "events" SET "end_at" = '2012-08-30 04:00:00.000000', "start_at" = '2012-08-30 01:00:00.000000', "updated_at" = '2012-08-22 20:02:15.554913' WHERE "events"."id" = 3
(2.5ms) COMMIT
=> true
1.9.3p194 :009 > e
=> #<Event id: 3, start_at: "2012-08-30 01:00:00", end_at: "2012-08-30 04:00:00", created_at: "2012-08-22 19:51:53", updated_at: "2012-08-22 20:02:15">
1.9.3p194 :010 >
「実際の」属性のセッターもカスタマイズする必要があると思いますが、デフォルトの動作を台無しにすることなくそれを行う方法がわかりません。考え?おそらく、これを処理するためのより「Rails-y」「callback-y」な方法がありますか?