web-dev-qa-db-ja.com

Rails

日時列starts_atを含むActiveRecordモデルEventがあります。 starts_atの日付と時刻が別々に選択されるフォームを提示したいと思います(例:日付の場合は"23-10-2010"、時刻の場合は"18:00")。これらのフィールドは単一の列starts_atでサポートされている必要があり、検証はstarts_atに対しても行われることが望ましいです。

もちろん、仮想属性とフックをいじくることもできますが、もっとエレガントな解決策が欲しいです。私はcomposed_ofrdoc )と属性デコレータ( 灯台のディスカッションgithub )の両方を試しましたが、成功しませんでした。

以下は、私が欲しいものの大まかな概要です。

class Event < ActiveRecord::Base
  validates_presence_of :start_date
end

# View
# On submission this should set start_date.
form_for @event do |f|
  f.text_field :starts_at_date         # date-part of start_date
  f.text_field :starts_at_time_of_day  # time-of-day-part of start_date
  f.submit
end

助けてくれてありがとう。

40
pgericson

Railsプロジェクトのために今日これを見ていて、この宝石に出くわしました:

https://github.com/shekibobo/time_splitter

DateTimeの設定は、特にWebフォームを介して、困難または見苦しいものになる可能性があります。適切なDatePickerまたはTimePickerを見つけるのは簡単ですが、両方で機能させるのは難しい場合があります。 TimeSplitterは、datetimeまたはtime属性の日付、時刻、時間、および分に対応するアクセサーを自動的に生成するため、異なるフォーム入力を使用して日時フィールドの異なる部分を設定するのは簡単です。

それはあなたのために仕事をするように見えます

9
asgeo1

ビューに_text_field_が必要ですか?

私の知る限り、_date_time_フィールドを作成し、2つの異なる入力フィールドを使用してフィールドのさまざまな部分を設定できます。

_form_for @event do |f|
  f.date_select :starts_at
  f.time_select :starts_at, :ignore_date => true
  f.submit
end
_

Rails日付と時刻の選択ヘルパーは5つの異なるパラメーター(年の部分にはstarts_at(1i)、月の部分には_2i_など)を設定するため、つまり、_date_select_は日付部分にのみ設定しますが、_:ignore_date => true_を_time_select_に渡すと、時間と分の部分のみが設定されます。

_text_field_が必要な場合、その方法はわかりませんが、フォームを送信する前に日時パラメーターを設定する前に、jQueryのマジックを使用することは可能かもしれません。

39
Frost

を使って date_selectおよびtime_selectは良い方法です。

しかし、私はtext_field日付(JavaScriptの日付ピッカーを使用できるようにするため)。

Strong_parametersまたはRails 4+:

models/event.rb

# Add a virtual attribute
attr_accessor :start_at_date

views/events/_form.html.haml

- # A text field for the date, and time_select for time
= f.label :start_at
= f.text_field :start_at_date, value: (f.object.start_at.present? ? f.object.start_at.to_date : nil)
= f.time_select :start_at, :ignore_date => true

controllers/events_controller.rb

# If using a date_select, time_select, datetime_select
# Rails expects multiparameter attributes
# Convert the date to the muiltiparameter parts
def event_params
  if !!params[:event] && (params[:event]["start_at(4i)"].present? || params[:event]["start_at(5i)"].present?)

    if params[:event][:start_at_date].present?
      start_at_date = params[:event][:start_at_date]
    else
      start_at_date = Date.today
    end
    year  = start_at_date.match(/^(\d{4})[\-\/]/)[1]
    month = start_at_date.match(/[\-\/](\d{2})[\-\/]/)[1]
    day   = start_at_date.match(/[\-\/](\d{2})$/)[1]
    params[:event]["start_at(1i)"] = year
    params[:event]["start_at(2i)"] = month
    params[:event]["start_at(3i)"] = day
  end
  ...
3
d_rail

エレガントなソリューションは date_time_attributegem を提供します:

class MyModel < ActiveRecord::Base
  include DateTimeAttribute

  date_time_attribute :starts_at
end

starts_at_dateおよびstarts_at_time 別々に:

form_for @event do |f|
  f.text_field :starts_at_date
  f.text_field :starts_at_time
  f.submit
end

# this will work too:
form_for @event do |f|
  f.date_select :starts_at_date
  f.time_select :starts_at_time, :ignore_date => true
  f.text_field  :starts_at_time_zone
  f.submit
end

# or
form_for @event do |f|
  f.date_select :starts_at_date
  f.text_field  :starts_at_time
  f.submit
end

また、タイムゾーンで遊んだり、Chronicを使用したりすることもできます。

2
Sergei Zinin

これは設計上の問題によるものですか? starts_atを日時データ型として保存し、次のようなものを使用すると、はるかに簡単になります。

http://puna.net.nz/timepicker.htm#

これは、モデルにある日付フィールドの上で実行されるだけです。

0
Chris Barretto