我试图创建一些嵌套PARAMS的事件,但我想返回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
是空的 - 什么是做到这一点的最好方法是什么?
您可以在您需要的属性,使用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
我不知道这是因为文档例如最终语法没有嵌套的属性,但我希望这点你在正确的方向。
虽然你可以叫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
如果PARAMS已完全无法使用,但对于其中一个属性缺失或空白应该通过验证处理更“正常”的情况下,提前保释。
这让你真正给用户/客户提供关于丢失的反馈和响应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