我有一个自动保存的表单。我希望能够运行验证并向用户返回错误消息,但我还想保存所有有效的属性。前端是有角度的,所以如果你期望一切有效的东西都会有点烦人。
我希望能够做到这样的事情:
# @user = <User name: "Chill Dude" favorite_color: "blue">
@user.save(name: '', favorite_color: "red")
@user.errors #=> ["Name cannot be null"]
@user.reload #=> <User name: "Chill Dude" favorite_color: "red">
我确定我可以提出一些重要的复杂解决方案,然后点击object.errors
,但我想知道是否有任何简单的rails-y方法可以做到这一点?
答案 0 :(得分:2)
您可以利用errors
对象,仅将错误的列重置为之前的值:
u = User.first
u.name = nil # invalid value
u.favorite_color = "red" # ok value
# run validations and set the errors object
u.valid?
# => false
# this shows the attributes with errors
u.errors.keys
# => [:name]
# restore the attributes with errors
u.restore_attributes(u.errors.keys)
# other attributes should stay changed:
u.favorite_color
# => "red"
# save should succeed now
u.save
# => true
请参阅Errors
和restore_attributes
文档。
更新:啊,我刚刚注意到你在问题中写了关于使用错误的大复杂解决方案,好吧,我认为这已经足够了:
# any model or ApplicationRecord in Rails 5
def save_valid_attributes
restore_attributes(errors.keys) unless valid?
save # or perhaps even save(validate: false) to speed things up,
# if validations are independent of each other
end
答案 1 :(得分:0)
注意:我不会称之为“rails-y”,但它应该有效。我宁愿不从UI发送空值。在这种情况下,rails(真的是ActiveRecord)正在拒绝无效的模型。
我强烈建议您在用户界面中查看处理方法。我在这里发现了一个看起来很有用的帖子:AngularJS form and null/empty values
也就是说,这可能是一个疯狂的想法,但如果我无法解决UI方面的问题,这就是我要做的。这将采用已发布的参数,并在更新模型之前拒绝那些空白参数。可以利用相同的逻辑来保存选项。对于帮助者来说,这可能是一个很好的选择,可以从控制器中删除额外的逻辑。
def update
clean_params = my_params.reject {|a| my_params[a].blank? }
if @model.update(clean_params)
# ...good
else
# ...bad
end
end
private
def my_params
params.require(:model).permit(:attr1, :attr2)
end
在此处查看有关拒绝的更多信息:http://docs.ruby-lang.org/en/2.0.0/Hash.html#method-i-reject