activerecord

    bullet 2.3.0 released

    25 Mar 2012

    bullet is a gem to help you increase your application's performance by reducing the number of sql requests it makes. Today I released bullet 2.3.0 to better support rails 3.1 and 3.2 and performance improved. It's a long time I didn't do any changes to bullet, let me tell you the story I work for bullet 2.3.0.

    At the beginning of this month, bullet got its 1000th watcher on github, I realized it's time to improve it e.g. speed up and compatible with edge rails.

    The first thing I did is to refactor tests. Before I created several rspec tests, but they are more like integration tests instead of unit tests, so I move them to spec/integration/ directory. Then I added a bunch of test units to cover all codes, which can promise the correctness of furth...

    Read More

    Tags 


    activerecord属性保护

    30 Jan 2010

    最近在看rails安全方面的书,第一部分就是关于生成activerecord对象的参数保护问题。平时一直使用,今天心血来潮想起要看看源代码是如何实现的。

    activerecord属性保护就是通过attr_accessible和attr_protected来声明哪些属性可以访问,哪些不可以访问。当然,这些保护只是针对new, create和update_attributes方法,对于直接使用attribute=就无能为力了。

    attr_accessible的源码为

    def attr_protected(*attributes)
      write_inheritable_attribute(:attr_protected, Set.new(attributes.map()) + (protected_attributes || []))
    end

    原来activerecord会生成一个attr_protected属性,来记录所有的需要被保护的字段

    同样attr_accessible会生成attr_accessible属性

    def attr_accessible(*attr...
    Read More

    Tags 


    ActiveRecord destroy之后的事情

    30 Aug 2009

    一般的Rails应用都在对象destroy之后自动跳转到另一个页面,不再去关心被destroy的对象如何了。其实被destroy的对象虽然从数据库中被删除了,但仍然存在于内存当中。

    举个例子吧,比如我们做个博客系统,有文章,有评论,当我们删除一个日志的时候,需要在日志中做下记录

    class Post
      after_destroy :log
    
      def log
        Logger.create(:action => 'destroy', :object_type => self.class, :object_id => self.id, :object_value => self.title)
      end
    end

    可见,我们是在post被删除之后再做日志记录,此时我们仍然能够得到post对象,并成功记录到日志系统中去。

    如果再加些BT的需求呢,要求在日志系统中同时记录子对象(即comments对象)的type, id和value。看看很简单,但是你会不会想到,comments在post之前就被删除了,我们去哪里拿这些数据呢?答案就是内存中

    class Post
      has_many...
    Read More

    Tags 


    default_scope影响attribute的default值

    25 Aug 2009

    之前有个需求,发表的文章需要审核之后才能显示,于是在Post类中加了一个default_scope

    default_scope :order => 'updated_at desc', :conditions => {:verify => true}

    之后就发觉每次创建的post对象,其verify值总是为true,除非手动设置verify=false。当然我在migration的时候已经设置verify的default为false了。很奇怪,于是看了下rails的源代码,其中是这么定义default_scope的

    def default_scope(options = {})
      self.default_scoping << { :find => options, :create => options[:conditions].is_a?(Hash) ? options[:conditions] : {} }
    end

    这里可以看到如果default_scope的conditions是一个Hash的话,那么这个Hash会被保存起来,并在对象initialize的时候生效

    ... Read More

    Tags 


    ActiveRecord Without Rails

    02 Jun 2009

    前几天写了个小程序,帮我选号买彩票。主要是去网上抓取历次的开奖号码,存到数据库,然后再做统计分析。

    因为程序很小,所以实在不想把Java这个大胖子叫出来,就简单地在vi下写了几十行的ruby代码。由于要用到数据库,自然想到了ActiveRecord,平时都是在Rails环境下用的,现在却是要让它脱离出来,闹独立。

    首先是在mysql中新建数据库:

    mysqladmin -uroot create caipiao

    接着当然应该是定义database.yml

    adapter: mysql
    encoding: utf8
    database: caipiao
    username: root
    password:
    socket: /var/run/mysqld/mysqld.sock

    定义migration,新建db/migrate目录,新建migration文件,注意前面加上数字前缀,001_xxx, 002_yyy,migration文件内容就和rails中的一模一样。

    class CreateRedBlueBalls < ActiveRecord::Migration
      def...
    Read More

    Tags 


    通过数组转置来组织ActiveRecord的conditions

    20 Apr 2009

    使用ActiveRecord的conditions最基本的方法就是数组:

    :conditions => ['first_name = ? and middle_name = ? and last_name = ?', 'George', 'W', 'Bush']

    更灵活的方法是使用Hash来组织:

    :conditions => {:first_name => 'George', :middle_name => 'W', :last_name => 'Bush'}

    这样在动态构建查询条件的情况非常有帮助,比如根据查询参数来构建conditions:

    conditions = {}
    conditions.merge!({:first_name => params[:first_name]}) if params[:first_name]
    conditions.merge!({:first_name => params[:middle_name]}) if params[:middle_name]
    conditions.merge!({:first_name => params[...
    Read More

    Tags