【问题标题】:Rails 3 - check that object is valid with params before updateRails 3 - 在更新之前使用参数检查对象是否有效
【发布时间】:2012-05-30 10:44:08
【问题描述】:

我有一个非常新手的问题。在更新模型之前,如何使用新参数检查模型对象是否有效?

我想改变它:

def update
  @obj = SomeModel.find( params[:id] )

  if @obj.update_attributes( params[:obj] )
    # That have been updated
  else
    # Ups, errors!
  end
end

类似的事情:

def update
  @obj = SomeModel.find( params[:id] )

  if @obj.valid_with_new_params( params[:obj] )
    @obj.update_attributes( params[:obj] )
  else
    # Ups, errors!
  end
end

【问题讨论】:

    标签: ruby-on-rails ruby ruby-on-rails-3 validation


    【解决方案1】:

    如果传递的参数没有生成有效的对象,则不会保存该对象,因此您可以使用自己的方式。您可以使用@obj.errors 数组查看错误(如果有)。

    【讨论】:

      【解决方案2】:

      update_attributes 方法验证对象,如果对象无效则返回 false。所以,你可以写:

      if @obj.update_attributes( params[:obj] )
        # That have been update
      else
        # Ups, errors!
      end
      

      【讨论】:

        【解决方案3】:

        您可以调用valid? 方法来运行验证。

        如果您的某些验证依赖于数据库中其他对象的状态,这并不能保证后续保存会成功。保存也可能由于与验证无关的原因(例如外键约束)而失败

        我不知道你为什么想要这种模式

        【讨论】:

        • 我正在保存一些不同模型的对象。所以我收集每个模型的验证错误,然后在一个弹出窗口中显示。
        【解决方案4】:

        要更新属性而不保存它们,您可以使用

        @obj.assign_attributes( params[:obj] )
        

        然后检查对象是否有效,可以调用

        @obj.valid?
        

        如果对象无效有效,你可以通过调用查看错误(仅在调用.valid?之后)

        @obj.errors
        

        如果对象有效的,可以调用保存

        @obj.save
        

        但是,所有这些通常都不是必需的。如果对象无效,则 ActiveRecord 不会将对象保存到数据库中,因此当您离开控制器操作时,所有属性更改都会被遗忘。

        另外,由于无效记录不会被保存到数据库中,您可以随时再次调用 Object.find() 来取回原始对象。

        【讨论】:

        • 在@obj.attributes(params[:obj])之后,调用@obj.save。
        • 在撰写本文时,此答案中显示的 attributes() 方法已弃用。请改用assign_attributes(new_attributes) 或别名attributes=(new_attributes)。因此,这个答案的第一行应该是@obj.assign_attributes( params[:obj] )。见ActiveRecord::AttributeAssignment
        • Re: assign_attributes(new_attributes) -- 请注意唯一的属性集是那些由参数哈希中的键命名的属性。所以如果你有一个现有的对象,你可以添加/合并属性的一个子集。
        • 对于好奇的人,这直接来自update(attributes) playbook(顺便说一下,别名为update_attributes(attributes))——View the source for update(attributes),你会看到assign_attributes(attributes),后面跟着save (在save 中,验证发生在实际持久/保存之前)。
        • @Justin,在 Rails 3.2.22 中不适合我,当我尝试分配像 @obj.assign_attributes( params[:obj] ) 这样的参数时,我的 @obj 变成 nil
        【解决方案5】:

        答案是你可以定义一个方法

        def valid_with_new_params(hash)
           self.attributes = hash
           valid?
        end
        

        但这是不必要的,因为如果 obj 成功更新,@obj.update_attributes(params[:obj]) 返回 true,否则返回 false。另请注意,update_attributes 方法在内部会在 @obj 上运行所有验证,以便在更新失败时可以使用 @obj.errors

        【讨论】:

        • 新版本的 Rails 中不推荐使用 attributes= 方法
        • 谢谢@apneadiving 不知道 :)
        【解决方案6】:

        更新属性而不保存属性

        @obj.attributes = params[:obj]   0r
        @obj.attributes = {:name => “Rob”}
        

        然后检查对象是否有效

        @obj.valid?
        

        检查是否有错误

        @obj.errors
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2021-02-25
          • 2020-05-15
          • 1970-01-01
          • 1970-01-01
          • 2020-04-26
          • 2011-01-19
          • 1970-01-01
          相关资源
          最近更新 更多