Подтвердить что ты не робот

Rails - получение сообщения об ошибке от модели, которая не является ошибкой проверки

Итак, у меня есть метод в модели резервирования, называемый add_equip. Этот метод делает некоторую проверку, чтобы убедиться, что добавленная часть оборудования действительна (не противоречит другому резервированию).

Проверки работают. Если добавленная часть оборудования не должна быть добавлена, это не так, и если это так.

Проблема заключается в том, что я не могу понять, как отправить сообщения обратно на контроллер, чтобы они были помещены во флэш-сообщение? Я знаю, что мне здесь что-то не хватает, но я уже несколько часов искал в Интернете и не могу найти никаких ясных объяснений о том, как передавать ошибки в резервную копию контроллера, если только они не являются ошибками проверки.

add_equip в reservations_controller

    def add_equip
    @reservation = Reservation.find(params[:id])
    @addedEquip = Equip.find(params[:equip_id])

    respond_to do |format|
     if @reservation.add_equip(@addedEquip)
        flash[:notice] = "Equipment was added"
        format.html { redirect_to(edit_reservation_path(@reservation)) }
     else
        flash[:notice] = @reservation.errors
        format.html { redirect_to(edit_reservation_path(@reservation)) }
     end
    end
  end

add_equip в модели резервирования

def add_equip equip
   if self.reserved.find_by_equip_id(equip.id)
     self.errors.add_to_base("Equipment Already Added")
     return false
   elsif !equip.is_available?(self.start, self.end)
     self.errors.add_to_base("Equipment Already Reserved")
     return false
   else
     r = Reserved.new
     r.reservation = self
     r.equip = equip
     r.save
   end
  end

Любая помощь будет принята с благодарностью. Я знаю, что у меня отсутствует что-то основное.

4b9b3361

Ответ 1

Использование add_to_base для хранения сообщения об ошибке кажется мне прекрасным, вам просто нужно выяснить, как его получить в представлении.

Как насчет:

flash[:notice] = @reservation.errors.full_messages.to_sentence

Предполагая, что вы собираетесь повторно отображать форму, вы также можете использовать:

<%= f.error_messages %>

Или, возможно:

<%= error_messages_for :reservation %>

Кроме того, вы можете использовать flash [: error], тогда вы можете по-разному покрасить его с помощью класса CSS.

Ответ 2

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

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

Например:

def add_equip
  @reservation = Reservation.find(params[:id])
  @addedEquip = Equip.find(params[:equip_id])

  respond_to do |format|
    if @reservation.add_equip(@addedEquip)
      flash[:notice] = "Equipment was added"
      format.html { redirect_to(edit_reservation_path(@reservation)) }
    else
      flash[:error] = 'Error adding equipment'
      format.html { render :action => :edit }
    end
  end
end

Теперь вы можете продолжать использовать обычные помощники формы для отображения сообщений об ошибках.

Кроме того, просто небольшое предложение для кода модели, попробуйте использовать i18n, когда это возможно (в том числе для флэш-сообщений в контроллере). Хотя это в основном личное предпочтение, он дает логичный дом для всех ваших сообщений и конкретного текста, а alos позволяет создавать общие или стандартные сообщения, которые можно изменить в одном месте, а не дублировать изменения в нескольких моделях и контроллерах.

например.

def add_equip equip
  if self.reserved.find_by_equip_id(equip.id)
    self.errors.add_to_base(:already_added)
    return false
  elsif !equip.is_available?(self.start, self.end)
    self.errors.add_to_base(:already_reserved)
    return false
  else
    r = Reserved.new
    r.reservation = self
    r.equip = equip
    r.save
  end
end