如果其他属性无效,有Rails保存有效属性吗?

时间:2016-05-20 18:50:22

标签: ruby-on-rails

我有一个自动保存的表单。我希望能够运行验证并向用户返回错误消息,但我还想保存所有有效的属性。前端是有角度的,所以如果你期望一切有效的东西都会有点烦人。

我希望能够做到这样的事情:

# @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方法可以做到这一点?

2 个答案:

答案 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

请参阅Errorsrestore_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