【问题标题】:How to handle date fields in a non-model Rails form?如何处理非模型 Rails 表单中的日期字段?
【发布时间】:2014-04-01 23:14:39
【问题描述】:

我正在使用ActiveModel 创建一个将与Rails 表单构建器一起使用的非模型对象。这是一个 Rails 3 项目。这是我到目前为止的一个例子:

class SalesReport
  include ActiveModel::Validations
  include ActiveModel::Conversion
  extend ActiveModel::Naming

  attr_accessor :promotion_code, :start_date, :end_date

  def initialize(attributes = {})
    attributes.each do |name, value|
      send("#{name}=", value)
    end
  end

  def persisted?
    false
  end
end

我碰巧在使用 HAML 和 simple_form,但这并不重要。最终,我只是使用标准 Rails 日期选择字段:

= simple_form_for [:admin, @report], as: :report, url: admin_reports_path do |f|
  = f.input :promotion_code, label: 'Promo Code'
  = f.input :start_date, as: :date
  = f.input :end_date, as: :date
  = f.button :submit

Rails 将日期字段拆分为单独的字段,因此在提交表单时,实际上提交了 3 个日期字段:

{
  "report" => {
    "start_date(1i)" => "2014",
    "start_date(2i)" => "4",
    "start_date(3i)" => "1"
  }
}

在我的SalesReport 对象中,我将参数分配给我的attr 方法,但是我收到一个错误,我没有start_date(1i)= 方法,我显然没有定义它。最终,我希望得到一个可以使用的 Date 对象,而不是 3 个单独的字段。

我应该如何处理我的非模型对象中的这些日期字段?

【问题讨论】:

    标签: ruby-on-rails forms activemodel


    【解决方案1】:

    在您的初始化中,您可以手动将属性中的值分配给类方法,然后在下面覆盖您的 start_dateend_date setter 方法。

    class SalesReport
      include ActiveModel::Validations
      include ActiveModel::Conversion
      extend ActiveModel::Naming
    
      attr_accessor :promotion_code, :start_date, :end_date
    
      def initialize(attributes = {})
        @promotion_code = attributes['promotion_code']
        year = attributes['start_date(1i)']
        month = attributes['start_date(2i)']
        day = attributes['start_date(3i)']
        self.start_date = [year, month, day]
      end
    
      def start_date=(value)
        if value.is_a?(Array)
          @start_date = Date.new(value[0].to_i, value[1].to_i, value[2].to_i)
        else
          @start_date = value
        end
      end
    
      def persisted?
        false
      end
    end   
    

    这应该允许您为设置器提供Date 实例或带有单独日期元素的Array,设置器会将正确的日期分配给@start_date。 只需对 @end_date 执行相同操作即可。

    希望对你有帮助。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2010-10-18
      • 1970-01-01
      • 2017-04-24
      • 2023-03-27
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多