本站首页    管理页面    写新日志    退出


«August 2025»
12
3456789
10111213141516
17181920212223
24252627282930
31


公告
 本博客在此声明所有文章均为转摘,只做资料收集使用。

我的分类(专题)

日志更新

最新评论

留言板

链接

Blog信息
blog名称:
日志总数:1304
评论数量:2242
留言数量:5
访问次数:7595218
建立时间:2006年5月29日




[Ruby on Rails]修复update_attribute(s)更新全部字段的问题
软件技术

lhwork 发表于 2007/2/8 10:07:46

这是前段时间有人讨论过的问题: 代码: 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  endendActiveRecord::Base.class_eval do  include ActiveRecord::ValidationsFixend 简单测试通过。


阅读全文(3091) | 回复(0) | 编辑 | 精华
 



发表评论:
昵称:
密码:
主页:
标题:
验证码:  (不区分大小写,请仔细填写,输错需重写评论内容!)



站点首页 | 联系我们 | 博客注册 | 博客登陆

Sponsored By W3CHINA
W3CHINA Blog 0.8 Processed in 0.330 second(s), page refreshed 144772111 times.
《全国人大常委会关于维护互联网安全的决定》  《计算机信息网络国际联网安全保护管理办法》
苏ICP备05006046号