Rails部分日期

时间:2014-04-06 13:25:42

标签: ruby-on-rails date ruby-on-rails-4

我的表有一个release_date列,以

格式保存
  

2002-02-01

在模型中我有

validates_date :release_date, :allow_blank => true

在我的新视图中,我有以下内容

<%= f.label :release_date, class: "control-label" %>
              <%= f.date_select :release_date, :start_year => Date.current.year, :end_year => 1970, :include_blank => true %>

给出三个单独的下拉菜单以选择日期。

我想要的是,当用户只知道年份,月份和年份时,可以选择部分日期。我认为这可能适用于相应的allow_blank标签,但它不会当前如果您选择月份和年份但将日期留空则不会将日期保存到数据库中。

我如何允许部分日期?最好使用与当前使用的格式相同的格式进行保存,以使我现有的数据无效。

在我的节目视图中,我使用此

调用release_date
<%= @miniature.release_date.strftime("%d %b %Y") unless @miniature.release_date.blank? %>

我希望能够在可用时显示整个日期,如果没有,则显示为

  

2002年2月

或只是

  

2002

这就是所有可用的。

2 个答案:

答案 0 :(得分:2)

我猜你的release_date应该是date列,这意味着创建记录需要完整日期,即使只有年份或年份+月份也是如此。

您可能需要一个整数列,例如date_mask,以告知哪些部分(年,月,日)可用,并修改控制器中的create操作以存储date_mask信息。

class MyController < ApplicationController
  def create
    #...
    if params[:my_model][:"release_date(2i)"] == ''
      # no month is given, insert fake month and day
      params[:my_model][:"release_date(2i)"] = '1'
      params[:my_model][:"release_date(3i)"] = '1'
      mask = 4 # 100
    elsif params[:my_model][:"release_date(3i)"] == ''
      # no day is given, insert a fake day
      params[:my_model][:"release_date(3i)"] = '1'
      mask = 6 # 110
    else
      # full-date
      mask = 7 # 111
    end
    # ...
    MyModel.create(my_model_params.merge(date_mask: mask))
    # ...
  end

  private

  def my_model_params
    params.require(:my_model).permit(:release_date, :date_mask)
  end
end

在您的模型中,创建方法release_date_display以根据release_datedate_mask

显示日期
class MyModel < ActiveRecord::Base
  #...
  def release_date_display
    if self.date_mask == 4
      return self.release_date.strftime('%Y')
    elsif self.date_mask == 6
      return self.release_date.strftime('%b %Y')
    else
      return self.release_date.strftime('%F')
    end
  end
  #...
end

对于现有数据,只需在data_mask列中插入7。

<强>更新

处理部分日期的示例:https://github.com/sibevin/partial-date-app

答案 1 :(得分:1)