shekibobo / time_splitter

Easily split Time/DateTime attribute accessors on your models for date, time, hour, and minute.

Home Page:https://github.com/shekibobo/time_splitter

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Allow empty time field

dkrusenstrahle opened this issue · comments

Hello,

Thank you for this useful gem!

How can I allow an empty time field?

You may need to be more specific. Any field values that aren't set should be nil, unless any of the other fields were set. Once you set any of the fields, the Time object is set, and it will have both a date and a time. If you truly need to separate Time and Date objects, you would probably be best to store two separate values. The main goal of this gem is to make it easy to set both the Date and Time parts of a Time object using separate form inputs.

This gem is really very helpfull, but I have the same problem as dkrusenstrahle. The params got the controllers are

"download_until_date"=>"", "download_until_hour"=>"", "download_until_min"=>""

and the download_until attribute is not set to nil, it remains untouched. I mean, it should be set to null.

@nagyt234 do you think you could provide a test case that would describe what behavior you thing this should have? In @dkrusenstrahle's case, it seems like they want to have a date field set, but the time field nil, which is not possible - this gem simply provides accessors to split a single time field to separate getters and setters.

In your case, it seems like you want to allow the entire download_until field to be nil if all fields are blank. In that case, if a time was previously set, then receiving blank values for any one of these should revert it to the appropriate zero value, while if all receive blank values, the original accessor (database field) should be set to nil. Is that correct?

it "can nullify the base time field by setting the date and time fields to nil" do
  thing = Thing.create!(starts_at: 3.days.from_now)
  expect(thing.starts_at_date).to eq 3.days.from_now.to_date
  thing.update!(starts_at_date: nil, starts_at_time: nil)
  expect(thing.starts_at).to be nil
end 

it "can nullify the base time field by setting date, hour, and minute fields to nil" do
  thing = Thing.create!(starts_at: 3.days.from_now)
  expect(thing.starts_at_date).to eq 3.days.from_now.to_date
  thing.update!(starts_at_date: nil, starts_at_hour: nil, starts_at_min: nil)
  expect(thing.starts_at).to be nil
end

@shekibobo, your test cases are exacly what I meant, with one extension:
if not all parts (date, time or date, hour, min) are set or unset, it should set an error.
I did not thought that you act so quickly :-) , so I've implemented alreaqdy a helper for workaround:

  # Set object.errors if not all parts are set or blank.
  # Set object.attribute to nil if datetime parts are blank
  # Can be used on attributes splitted by 'split_accessor' of 'time_splitter' gem
  def sanitize_datetime object, attr, params
    date = params["#{attr}_date"]
    hour = params["#{attr}_hour"]
    min  = params["#{attr}_min"]

    if [ date.blank?, hour.blank?, min.blank? ].uniq.size == 2
      object.errors.add attr, I18n.t(:set_all_parts_or_no_one)
      return false
    end

    object.write_attribute(attr,nil) if date.blank?

    return true
  end

BTW: I'm Hungarian and you have a traditional Hungarian name (Kovach=Kovács=Smith).

@nagyt234 You should be able to set the date on its own or the time, hours, or minutes on their own. If any of them are set, I think it should just zero out that part of the time object.

i.e.

thing.update(starts_at_date: Date.today, starts_at_hour: 3, starts_at_min: nil)
thing.starts_at_date
# => Date.today
thing.starts_at_time
# => 3:00

thing.update(starts_at_date: nil, starts_at_time: "3:00")
thing.starts_at
# => default date, time 3:00

The second case gives me pause, but I feel like falling back to the default value if any of these are blank would be appropriate. Only in the case where all argument combinations ([:date, :time], [:date, :hour, :min] are blank that the entire value should revert to nil.

@shekibobo Your first case is acceptable. In the second case to fall back to the default value is not a good idea, it will set a datetime value to "0000-01-01 03:00" without validation error.