Похоже, вы также столкнетесь с проблемой, когда ваше представление будет отображать форму, в которой скрытое значение next_month
будет 13, или предыдущее будет 0 - оба из которых будут недействительными. .
Вы также устанавливаете по умолчанию год и месяц logi c в представлении. Как правило, вам будет удобнее, если установка месяца и года выполняется в одном месте - в контроллере.
Переместите все лог c, включая то, как определить, что будет следующим / предыдущим, в контроллеру и сохраните простоту представления:
<%= form_tag facility_directory_path(@facility), method: :get, class: '' do %>
<%= hidden_field_tag 'current_month', @month %>
<%= hidden_field_tag 'current_year', @year %>
<%= submit_tag 'Previous Month', class: 'button' %>
<%= submit_tag 'Next', class: 'button ui basic blue small' %>
<% end %>
Эта форма в представлении теперь просто содержит текущее состояние (месяц и год), а также предыдущее и следующее. Нет расчета месяца или настройки по умолчанию.
Контроллер
Затем в вашем контроллере вы можете определить, если:
- Не было ввода формы (по умолчанию использовать текущий месяц)
- Была нажата кнопка поиска (использовались выпадающие список года и месяца)
- Нажата следующая или предыдущая кнопки.
Значение нажатой кнопки передается контроллеру, поэтому, если будет нажата следующая или предыдущая кнопка, вы увидите, что params[:commit]
будет равно либо «Предыдущий месяц», либо «Следующий». И у вас также будут params [: current_year] и params [: current_month].
Убедитесь, что ваш контроллер создает @year и @month по умолчанию в качестве текущего.
ниже должны охватывать все эти случаи.
if params[:commit] == "Previous Month" || params[:commit] == "Next"
# Handle preview/next buttons
now = Date.new(params[:current_year].to_i, params[:current_month].to_i, 1)
if params[:commit] == "Previous Month"
target_date = now - 1.month
else
target_date = now + 1.month
end
elsif params.has_key?(:select)
# Handle the select drop down
target_date = Date.new(params[:select][:year].to_i, params[:select][:month].to_i)
else
# Handle the default case - the first day of the current month
target_date = Date.new(Date.today.year, Date.today.month, 1)
end
@year = target_date.year.to_i
@month = target_date.month.to_i
# You can now consolidate the Active Record query into one query which handles all cases
@facility_records = @facility.chart_records.order(created_at: :desc).where(created_at: target_date..target_date+1.month)
Используя этот подход, вы можете иметь один запрос Active Record, который работает во всех случаях.
Лучшее, что можно избежать в будущем, - это :
- Держите как можно больше logi c вне поля зрения
- Установите значения по умолчанию для действия в контроллере (или модели)
- Создайте свой
- Знайте, что вы можете прочитать значение нажатой кнопки.
Надеюсь, это поможет в настоящее время и в будущем.