The Ruby On Rials Gudie -- Active Record Callbacks

来源:互联网 发布:python 实现api接口 编辑:程序博客网 时间:2024/06/06 17:12

这一篇讲了你的Active Record objects的整个生命过程。

在rails中,objects可以created,updated,destroyed。rails允许你before或者after上述操作时候进行逻辑操作。

这章主要讲的就是在对于model的各种操作的before或者after时可以采用的操作。对于所有的操作,总体来说有两种方式:

一、注册一个函数在回调函数处,这里填上函数的名字,然后再定义这个函数。这里要声明的是,最好这个函数定义为protected的或者private的,目的是为了封装,避免这个接口暴露。大体形式如下(这种形式主要是在我们的回调函数比较复杂的时候使用)

classUser < ActiveRecord::Base  validates:login,:email, presence: true   before_validation:ensure_login_has_a_value #before_validation是一个回调函数的名称   protected  defensure_login_has_a_value    iflogin.nil?      self.login = email unlessemail.blank?    end  endend


二、直接用一个proc块放在后面,这种形式主要适用于我们后面仅有一两句代码的简单形式

classUser < ActiveRecord::Base  validates:login,:email, presence: true   before_createdo|user|    user.name = user.login.capitalize ifuser.name.blank?  endend


下面我们说说可以使用的回调函数(注意,下面每个小块中出现的回调函数次序都是在该情况下回调函数被调用的次序)

1.Creating an Object(比如,创建一个object时,最先调用before_validation最后调用after_save)

  • before_validation #validation验证前
  • after_validation #validation验证后
  • before_save #存储前
  • around_save #存储时
  • before_create #创建前
  • around_create #创建时
  • after_create #创建后
  • after_save #存储后
2. Updating an Object

  • before_validation
  • after_validation
  • before_save
  • around_save
  • before_update
  • around_update
  • after_update
  • after_save

3. Destroying an Object

  • before_destroy
  • around_destroy
  • after_destroy
4. after_initialize 和after_find

after_initialize这个回调函数将在object实例化后调用,也就是执行new或者从数据库加载model时。你可以用它代替直接重写initialize函数

after_find这个回调函数在从数据库加载modle时调用(其实就是find什么的),当同时定义了after_initialize函数,after_find将在after_initialize之前调用,通过下面的例子可以看出来

classUser < ActiveRecord::Base  after_initializedo|user|    puts"You have initialized an object!"  end   after_finddo|user|    puts"You have found an object!"  endend >> User.newYou have initialized an object!=>#<User id: nil> >> User.firstYou have found an object!You have initialized an object!=>#<User id: 1>


下面我们再说说哪些函数会跳过这些callbacks(通过名字大概可以看出每个函数是什么意思,后面还会讲)

  • decrement
  • decrement_counter
  • delete
  • delete_all
  • increment
  • increment_counter
  • toggle
  • touch
  • update_column
  • update_columns
  • update_all
  • update_counters

最后,我们可以选择性的选择是否执行callback

其实就是配合使用if或者unless,只有if或者unless成立时才会执行。其实就是一个参数

例子如下

classOrder < ActiveRecord::Base  before_save:normalize_card_number,if::paid_with_card?end

if是key,指向一个object。

可以是symbol(符号),就像上面的,要求后面是一个函数的名字

可以是字符串,要求是可执行的rails代码

classOrder < ActiveRecord::Base  before_save:normalize_card_number,if:"paid_with_card?"end

可以是proc块,要求返回true或false

classOrder < ActiveRecord::Base  before_save:normalize_card_number,    if:Proc.new{ |order| order.paid_with_card? }end

还有一点,事务处理callback

有两个额外的callback,after_commit 和 after_rollback,这两个函数和after_save相似,但也不同,他们在数据库commit或者rollback才会调用的。这一点在你的系统要和其他系统共同处理的时候。最简单的例子就是当我们设计一个文件管理系统时,我们的数据库记录着我们有那些文件路径,而这些文件在磁盘中存着。我们删除一条数据库记录时或者增加一条数据库记录时可能会有文件与存储的不一致问题,这个用这类回调函数最合适了。

对了,忘了一点,我们所有的callback都可以使用on这个参数约定它作用的函数,on指向一个数组,里面存着函数名。

下面是个例子

classPictureFile < ActiveRecord::Base  after_commit:delete_picture_file_from_disk,:on=> [:destroy]#在destroy函数调用   defdelete_picture_file_from_disk    ifFile.exist?(filepath)      File.delete(filepath)    end  endend

假如你不加上on,那么每个action都会调用这个回调函数的



原创粉丝点击