Как остановить создание, если значение параметра пустое / отсутствует? - PullRequest
0 голосов
/ 10 февраля 2019

Я пытаюсь создать событие с некоторыми вложенными параметрами, но я хочу вернуть 400, если некоторые параметры пусты.Есть ли какие-то встроенные способы сделать это без проверки params и возврата рано?

для примера:

event = Event.create! params.require(:event).permit(
      :name,
      :owner_id,
      attachments: [],
      location_attributes: [
        :custom,
        :building,
        :street_1,
        :street_2,
        :city,
        :state,
        :postal,
        :country,
        :latitude,
        :longitude,
      ],
    )

Допустим, я хочу отклонить, если latitude и longitudeпусты - какой лучший способ сделать это?

Ответы [ 2 ]

0 голосов
/ 10 февраля 2019

Хотя вы можете просто позвонить require несколько раз:

def event_params
  params.require(:event).require(:location_attributes).tap do |p|
    p.require(:latitude)
    p.require(:longitude)
  end
  # ...
  params.require(:event).permit(
      :name,
      :owner_id,
      attachments: [],
      location_attributes: [
        :custom,
        :building,
        :street_1,
        :street_2,
        :city,
        :state,
        :postal,
        :country,
        :latitude,
        :longitude,
      ]
    )
end

Это действительно раздувает ваш контроллер.

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

Методы взрыва, такие как create!, должны действительно использоваться только в неинтерактивном контексте (таком как начальные файлы) или когда вы используете транзакцию инеобходимо откатить транзакцию при сбое.

Таким образом, вы можете использовать .require для раннего освобождения под залог, если параметры полностью непригодны, но для более «нормального» случая, когда атрибут отсутствует или должен быть пустымобрабатывается валидациями.

Это позволяет вам фактически предоставить отзыв пользователю / клиенту о том, что отсутствует, и ответ 422. на самом деле более уместен.

def create
   @event.new(event_params)
   if @event.save
     respond_to do |f|
       f.html { redirect_to @event }
       f.json { status :created, location: @event }
     end
   else
     respond_to do |f|
       f.html { render :new}
       f.json { status :unprocessable_entity }
     end
   end
end

class Event < ApplicationRecord
  has_many :locations
  accepts_nested_attributes_for :locations
  validates_associated :locations
end

class Location < ApplicationRecord
  belongs_to :event
  validates_presence_of :latitude, :longitude
end
0 голосов
/ 10 февраля 2019

Вы также можете использовать require для нужных вам атрибутов, но это немного сложно.Посмотрите на последний пример здесь https://edgeapi.rubyonrails.org/classes/ActionController/Parameters.html#method-i-require

В вашем случае это будет что-то вроде:

params.require(:event).permit(
  :name,
  :owner_id,
  attachments: [],
  location_attributes: [
    :custom,
    :building,
    :street_1,
    :street_2,
    :city,
    :state,
    :postal,
    :country,
    :latitude,
    :longitude,
  ],
).tap do |event_params|
  event_params[:location_attributes].require(:latitude, :longitude)
end

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

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