Оценка точек по времени по месяцам, но без ссылки на годы в Rails - PullRequest
0 голосов
/ 14 марта 2010

К вашему сведению, в первоначальном описании этого вопроса есть некоторое совпадение с вопросом , который я задал вчера , но вопрос другой.

В моем приложении есть пользователи, у которых есть сезонные продукты. Когда пользователь выбирает продукт, мы позволяем ему также выбрать сезон продукта. Мы достигаем этого, позволяя ему выбрать дату начала и дату окончания каждого продукта.

Мы используем date_select для создания двух наборов раскрывающихся списков: один для даты начала и один для даты окончания.

Включая годы не имеет смысла для нашей модели. Поэтому мы используем опцию: discard_year => true

Когда вы используете discard_year => true, Rails устанавливает год в базе данных, он просто не отображается в представлениях. В нашем приложении Rails устанавливает все годы на 0001 или 0002. Да, мы могли бы сделать это 2009 и 2010 или любую другую пару. Но дело в том, что мы хотим, чтобы месяцы и дни функционировали независимо от конкретного года. Если бы мы использовали 2009 и 2010 годы, то эти даты были бы неправильными в следующем году, потому что мы не ожидаем, что эти записи будут обновляться каждый год.

Моя проблема заключается в том, что нам необходимо динамически оценивать доступность продуктов на основе их отношения к текущему месяцу. Например, предположим, что это 15 марта. Независимо от года мне нужен метод, который мог бы сказать мне, что продукт, доступный с октября по январь, сейчас недоступен.

Если бы мы использовали реальные годы, это было бы довольно просто.

Например, в модели продуктов я могу сделать это:

def is_available?
  (season_start.past? && season_end.future?)
end

Я также могу оценить start_date и end_date против current_date

Однако в настройке, которую я описал выше, где у нас есть произвольные годы, которые имеют смысл только по отношению друг к другу, эти методы не работают. Например, is_available? вернет false для всех моих продуктов, потому что их конечная дата - 0001 или 0002.

Что мне нужно, так это метод, подобный тем, которые я использовал в качестве примеров выше, за исключением того, что они сравниваются с current_month вместо current_date и прошлым? и будущие месяцы вместо лет.

Я понятия не имею, как это сделать или есть ли в Rails какие-либо встроенные функции, которые могут помочь. Я изучил все методы / помощники по дате и времени в документации по API, но я не вижу ничего эквивалентного тому, что я описываю.

Спасибо.

Ответы [ 2 ]

0 голосов
/ 14 марта 2010

Установите год текущей даты равным 1000 и выполните сравнение диапазона с датами начала и окончания.

def is_available?
  t = Date.today
  d = Date.new(1000, t.month, t.day)
  (season_start..season_end).include?(d) or 
     (season_start..season_end).include?(d+1.year) 
end

Второе сравнение, приведенное выше, касается следующего сценария:

Допустим, сегодня 15 января, а сезон с октября по февраль. По нашей логике мы установили дату 15 января 1000. Эта дата не будет в пределах 1 октября - 1 марта 1 марта. Поэтому мы проводим второе сравнение где мы продвигаем дату на год до 15 января 1001 года, что находится в пределах диапазона.

0 голосов
/ 14 марта 2010

Возможно, вы захотите отказаться от использования объектов Date. Что, если season_start_month и season_end_month были целыми числами 1–12, установленными с помощью раскрывающегося списка? Тогда когда вы делаете is_available? Для сравнения вы можете динамически создать полную дату для season_start, выполняя некоторые математические расчеты для переходов с декабря по январь. Это может использовать некоторый рефакторинг, и не тестируется, но должно сработать. Предполагается, что season_start_month и season_end_month являются целыми числами, хранящимися в этой модели:

class Product < ActiveRecord::Base
  def is_available?
    now = Time.now
    season_start < now && now < season_end
  end

  def season_start
    now = Time.now
    current_month = now.month
    season_start_year = season_start_month < current_month ? now.year : now.year - 1
    Time.local(season_start_year, season_start_month)
  end

  def season_end
    now = Time.now
    current_month = now.month
    season_end_year = season_end_month > current_month ? now.year : now.year + 1
    Time.local(season_end_year, season_end_month)
  end
end
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...