How to handle date fields in a non-model Rails form?

穿精又带淫゛_ 提交于 2020-01-15 04:25:08

问题


I am creating a non-model object that will be used with a Rails form builder by using ActiveModel. This is a Rails 3 project. Here's an example of what I have so far:

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

I happen to be using HAML and simple_form, but that's not important. Ultimately, I'm just using standard Rails date select fields:

= 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 splits up the date fields into individual fields, so when the form is submitted, there are actually 3 date fields that are submitted:

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

In my SalesReport object, I'm assigning the params to my attr methods, but I'm getting an error that I don't have a start_date(1i)= method, which I obviously haven't defined. Ultimately, I'd like to end up with a Date object that I can use instead of 3 separate fields.

How should I handle these date fields in my non-model object?


回答1:


In your initialization you could manually assign the values from attributes to the class methods and down below override you start_date and end_date setter methods.

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   

This should allow you to give the setter a Date instance or an Array with the separate date elements and the setter will assign the correct date to @start_date. Just do the same for @end_date.

Hope this can help you.



来源:https://stackoverflow.com/questions/22798691/how-to-handle-date-fields-in-a-non-model-rails-form

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!