Как мне запретить пользователям бронировать в прошлом Ruby DateTime? - PullRequest
0 голосов
/ 04 мая 2018

Я создал урок бронирования для пользователей, чтобы они могли забронировать своих инструкторов. Текущая проблема, с которой я сталкиваюсь, заключается в следующем: как я могу запретить пользователю бронировать в прошлом? Я использовал DateTime.

Другая проблема, если пользователь устанавливает начальный DateTime, как мне сделать так, чтобы конечный DateTime был меньше начального DateTime?

Я не пытался, может быть, у меня есть предложения. Текущий код показывает, как остановить двойное бронирование.

_form.hmtl.erb

<%= form_for(@lesson) do |f| %>

  <div class="field">
  <%= f.label :user_id %><br>
    <%= f.number_field :user_id %>
  </div>
  <div class="field">
    <%= f.label :lesson_start_date_time %><br>
    <%= f.datetime_select :lesson_start_date_time %>
  </div>
  <div class="field">
    <%= f.label :lesson_end_date_time %><br>
    <%= f.datetime_select :lesson_end_date_time %>
  </div>
  <div class="actions">
    <%= f.submit %>
  </div>
<% end %>

Lesson.rb

class Lesson < ActiveRecord::Base


belongs_to :user

validate :lessons_must_not_overlap

private

def lessons_must_not_overlap
   return if self
          .class
          .where.not(id: id)
          .where(user_id: user_id)
          .where('lesson_start_date_time < ? AND lesson_end_date_time > ?', lesson_end_date_time, lesson_start_date_time)
          .none?

   errors.add(:base, 'Overlapping lesson exists')
end

end

Ответы [ 2 ]

0 голосов
/ 04 мая 2018

Вы никогда не должны доверять пользовательскому вводу (поэтому любые изменения в html не имеют значения)

Вам просто нужно проверить даты, полученные от пользователя (сохранить проверки как можно более простыми, одна проверка должна нести одну ответственность)

validates :lesson_end_date_time, :lesson_start_date_time, presence: true
validate :start_date_in_future, :dates_has_positive_length

private

def start_date_in_future
  return if lesson_start_date_time.blank?
  return if lesson_start_date_time >= Date.current
  errors.add(:lesson_start_date_time, :invalid)
end

def dates_has_positive_length
  return if lesson_end_date_time.blank? || lesson_start_date_time.blank?
  return if lesson_end_date_time >= lesson_start_date_time
  errors.add(:lesson_end_date_time, :invalid)
end
0 голосов
/ 04 мая 2018

Просто добавьте еще одну проверку для проверки

  1. start date в прошлом
  2. end_date меньше start_date

Дайте этому попытку

validate :datetime_eligibility

private

#...

def datetime_eligibility
  # Check if `start_date` is less than `current time`
  if lesson_start_date_time < Time.current 
    errors.add(:base, "can't be in past")
  # Check if `end_date` is less than `start_date`
  elsif  lesson_end_date_time < lesson_start_date_time
    errors.add(:base, 'start date should be less than end date')
  end
end

Примечание: всегда сравнивайте дату и время с Time.current вместо Time.now, чтобы избежать проблем TimeZone с приложениями

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...