Хотя вы можете просто позвонить 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