`
qiezi
  • 浏览: 497715 次
  • 性别: Icon_minigender_1
  • 来自: 上海
社区版块
存档分类
最新评论

[RoR] 修复update_attribute(s)更新全部字段的问题

    博客分类:
  • Ruby
阅读更多
这是前段时间有人讨论过的问题:
代码:

order = Order.find(1)
order.update_attribute(:status, 'finished')

假定orders表有10个字段,你只想更新其中一个,但active record会生成一个更新全部字段的SQL语句,假定其中一个字段值长度是20K,这个负担可能会有些重。

我尝试解决这个问题,写了个简单的插件:
代码:

module ActiveRecord
  class Base
    def update_attribute(name, value)
      update_attributes(name => value)
    end

    def update_attributes(new_attributes)
      return if new_attributes.nil?
      attributes = new_attributes.dup
      attributes.stringify_keys!
      self.attributes = attributes
      update(attributes)
    end

    private
      def update(attrs = nil)
        connection.update(
          "UPDATE #{self.class.table_name} " +
          "SET #{quoted_comma_pair_list(connection, attributes_with_quotes(false, attrs))} " +
          "WHERE #{self.class.primary_key} = #{quote(id)}",
          "#{self.class.name} Update"
        )
       
        return true
      end

      def attributes_with_quotes(include_primary_key = true, attrs = nil)
        (attrs || attributes).inject({}) do |quoted, (name, value)|
          if column = column_for_attribute(name)
            quoted[name] = quote(value, column) unless !include_primary_key && column.primary
          end
          quoted
        end
      end
  end
end


attributes_with_quotes函数的参数搞这么复杂,原因是我想即便是用这段代码替换库里面的部分,也不影响原有代码的正常功能。

可以简单测试一下上面的例子,它生成的SQL语句会简洁很多,大概是这样子:
UPDATE orders SET "status" = 'finished' WHERE id = 1

已发现的BUG和修复:

1、没有调用validation (by cookoo)。由于原有代码调用save,而save被覆盖成有验证的代码,所以具有验证功能。解决办法是增加一段代码:

module ActiveRecord
  module ValidationsFix
    
def  self.append_features(base)  #  :nodoc:
      super
      base.class_eval do
        alias_method :update_attributes_without_validation, :update_attributes
        alias_method :update_attributes, :update_attributes_with_validation
      end
    end

    
def  update_attributes_with_validation(new_attributes)
      
return   if  new_attributes.nil?
      attributes = new_attributes.dup
      attributes.stringify_keys!
      self.attributes 
=  attributes

      
if  valid?
        update_attributes_without_validation(attributes)
      
else
        
return  false
      end
    end
  end
end

ActiveRecord::Base.class_eval do
  include ActiveRecord::ValidationsFix
end

简单测试通过。

分享到:
评论
4 楼 rainchen 2007-07-19  
另外,你设置的private update方法,冲掉了原有的public update方法:http://api.rubyonrails.org/classes/ActiveRecord/Base.html#M000996
3 楼 rainchen 2007-07-19  
想到update_attribute和update都用svae的一个理由是:
单独跟新某字段会忘记更新 updated_at 这种魔术字段

所以你这个插件应该加上这个?否则还是改下方法名,以免改变了原有期待的行为太多。
2 楼 rainchen 2007-07-18  
晕,忘了帖ticket的URL:
http://dev.rubyonrails.org/ticket/5961

btw,评论不能修改?
1 楼 rainchen 2007-07-18  
这个ticket是你报的吗?

为什么Rails的开发组坚决要一次更新所有的字段(update_attribute和update方法都是这样)?

如果开发组始终不承认这是个bug,我觉得不如改个方法名如update_particular_attribute之类,作为插件使用,发布到这里:http://agilewebdevelopment.com/plugins/search?search=update+attribute*

相关推荐

    ror_invoicing_frontend

    ror_invoicing_frontend项目设置yarn install编译和热重装以进行开发yarn serve编译并最小化生产yarn build整理和修复文件yarn lint自定义配置请参阅。

    BCGSoft[1].Professional.Editor.v6.75-ROR.ZIP_BCGSoft

    bcgsoft professional editor + crack file

    ROR_shopping_microservice:用Sinatra制成

    【标题】"ROR_shopping_microservice:用Sinatra制成" 涉及的主要知识点是Ruby编程语言以及Sinatra框架的应用。Sinatra是一款轻量级的Web应用框架,用于快速开发简洁、高效的Web服务。在Ruby社区中,它因为其简洁的...

    ruby_full:RoR_Full_29 :: Ruby_reports

    Ruby_full: RoR_Full_29 :: Ruby_reports 涵盖了全面的Ruby on Rails(RoR)开发中的报告生成技术。Ruby是一种面向对象的编程语言,以其简洁、优雅的语法著称,而Ruby on Rails是基于Ruby构建的一个开源Web应用框架...

    [转]完美的Tree

    同时,"工具"可能意味着这个树结构可能被用作解决特定问题或集成到开发工具中的实用组件。 【文件名称列表】:“完美的Tree”可能是压缩包内的主要文档,可能是一个HTML页面或Markdown格式的博客文章,包含了完整的...

    ROR_care_compass

    问题? 问题? 需要帮忙? 询问带有标签“ railsapps”的堆栈溢出。 您的应用程序在README文件中包含诊断。 报告任何问题时,请提供README文件的副本。 如果该应用程序无法正常运行,请并提供诊断信息。Ruby on ...

    ror_skeletal_app

    自述文件该自述文件通常会记录启动和运行应用程序所需的所有步骤。 您可能要讲的内容: Ruby版本系统依赖配置数据库创建数据库初始化如何运行测试套件服务(作业队列,缓存服务器,搜索引擎等) 部署说明...

    ror_blog_app

    自述文件该自述文件通常会记录启动和运行应用程序所需的所有步骤。 您可能要讲的内容: Ruby版本系统依赖配置数据库创建数据库初始化如何运行测试套件服务(作业队列,缓存服务器,搜索引擎等) 部署说明...

    ror_auth_sp21

    自述文件该自述文件通常会记录启动和运行应用程序所需的所有步骤。 您可能要讲的内容: Ruby版本系统依赖配置数据库创建数据库初始化如何运行测试套件服务(作业队列,缓存服务器,搜索引擎等) 部署说明...

    RoR_API_TDD:Udemy的REST API与Ruby on Rails课程

    自述文件 带有TDD的Rails API Udemy的课程带有Ruby on Rails的REST API 您可能要讲的内容: Ruby版本:2.7.0 Rails版本:5.2.4.4 组态 数据库创建 数据库初始化 测试套件:Rspec 服务(作业队列,缓存服务器,...

    RoR_julia_eg:通过 ZMQ 使用 Julia 链接的 Ruby on Rails Web 应用程序示例

    此示例展示了一种通过 ZMQ 将 Ruby on Rails Web 应用程序与 Julia 连接的方法。 ... 我只是在学习,我希望这篇文章对你有所帮助。... curl -sSL https://get.rvm.io | bash -s stable --rails 我更喜欢使

    RoR性能优化经验谈

    RoR(Ruby on Rails)是一种流行的开源Web开发框架,以其高效和简洁的代码著称。然而,随着网站规模的增长,性能优化成为必不可少的环节。在本文中,我们将探讨一些RoR性能优化的关键方面,主要基于JavaEye网站在...

    ror

    NULL 博文链接:https://xuxiangpan888.iteye.com/blog/266696

    ror中文资料

    **Ruby on Rails(简称RoR)中文资料** Ruby on Rails(RoR)是一个基于Ruby编程语言的开源Web应用框架,遵循MVC(Model-View-Controller)架构模式,旨在简化Web开发过程,提高开发效率。RoR强调“约定优于配置”...

    ROR 文件的上传与下载

    ### ROR 文件的上传与下载:深入解析与实践 在Ruby on Rails(简称ROR)框架下,处理文件的上传与下载是一项常见的需求,尤其是在构建包含媒体内容的应用程序时。本文将基于给定的文件信息,详细阐述如何在Rails...

    神经网络ror resenet模型

    **神经网络Ror ResNet模型详解** 在深度学习领域,ResNet(残差网络)模型是具有里程碑意义的创新,由He et al.在2015年提出。该模型解决了深度神经网络训练中的梯度消失问题,允许构建非常深的网络结构。而“Ror”...

    初探ROR

    **初探ROR** Ruby on Rails(简称ROR)是一个基于Ruby编程语言的开源Web应用程序框架,它遵循MVC(模型-视图-控制器)架构模式,旨在促进开发过程的简洁性和效率。Ruby on Rails的核心理念是“Don't Repeat ...

    RoR选题方向—源代码

    Ruby on Rails(RoR)是一种基于Ruby语言的开源Web应用程序框架,它遵循MVC(Model-View-Controller)架构模式,旨在简化Web开发过程。在这个选题方向中,我们主要探讨的是与RoR相关的源代码分析和学习。源代码是...

    ROR安装必备所有架包

    在Ruby on Rails(ROR)开发环境中,安装和配置正确的依赖包是至关重要的。这个压缩包包含了一系列用于ROR框架的基础组件,但不包括Ruby本身。让我们深入了解一下这些包的作用和重要性。 首先,`actionpack`是Rails...

    ror实例

    Ruby on Rails(简称RoR或Rails)是一种基于Ruby语言的开源Web应用框架,它遵循Model-View-Controller(MVC)架构模式,旨在提高开发效率并提供简洁、优雅的代码结构。"ror实例"可能指的是在学习或实践中,通过创建...

Global site tag (gtag.js) - Google Analytics