【问题标题】:Have Rails save valid attributes even if other attributes are invalid?即使其他属性无效,Rails 是否也会保存有效属性?
【发布时间】:2016-09-18 03:28:33
【问题描述】:

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

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

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

【问题讨论】:

  • yr 保存@user 然后调用@object.reload,实际上如果对其进行验证,它不应该保存它。
  • 显然这是默认行为。我在问是否有办法保存有效属性?
  • 你保存了用户,但是对象有之前的数据和错误,所以它们不能属于更新的用户。验证后:@user.errors
  • 这是奇怪的行为,请添加你的模型来发布
  • @МалъСкрылевъ 有完整的代码示例

标签: ruby-on-rails


【解决方案1】:

您可以利用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 文档。

更新:啊,我刚刚注意到你在问题中写了big complex solution using errors,好吧,我认为这已经足够了:

# 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

【讨论】:

  • 太棒了,为阅读问题和发布精彩回复鼓掌两声
【解决方案2】:

注意:我不会称其为“rails-y”,但它应该可以工作。我宁愿不从 UI 发送空值。在这种情况下,rails(真正的 ActiveRecord)正在拒绝无效模型。

我强烈建议在 UI 中查看处理此问题。我在这里找到了一个看起来很有用的帖子: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

【讨论】:

  • 我认为您在这里缺少核心概念。重点不是处理空值,重点是处理任何无效属性
猜你喜欢
  • 1970-01-01
  • 2022-09-25
  • 2010-12-04
  • 2012-01-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-04-30
相关资源
最近更新 更多