`
tes
  • 浏览: 7704 次
  • 性别: Icon_minigender_1
  • 来自: 济南
最近访客 更多访客>>
社区版块
存档分类
最新评论

《Rails Recipes》Part II Database Recipes 知识点总结 四

阅读更多
Add Behavior to Active Record Associations
先贴上数据迁移代码
class AddStudentsTables < ActiveRecord::Migration
def self.up
create_table :students do |t|
t.column :name, :string
t.column :graduating_year, :integer
end
create_table :grades do |t|
t.column :student_id, :integer
t.column :score, :integer # 4-point scale
t.column :class, :string
end
end
def self.down
drop_table :students
drop_table :grades
end
end




模型设置代码


class Student < ActiveRecord::Base
has_many :grades
end

class Grade < ActiveRecord::Base
end






有两种方式在模型关联上添加额外的方法
第一种方法
先建立一个module

module GradeFinder
def below_average
find(:all, :conditions => ['score < ?' , 2])
end
end



然后拓展mode
require "grade_finder"
class Student < ActiveRecord::Base
#注意:extend
has_many :grades, :extend => GradeFinder
end




第二种较简单 直接把定义的方法通过'块'赋给has_many关系的声明

class Student < ActiveRecord::Base
has_many :grades do
def below_average
find(:all, :conditions => ['score < ?' , 2])
end
def foo
raise self.inspect
end
end
end





chad> ruby script/console
>> Student.find(1).grades.below_average
=> [#<Grade:0x26aecc0 @attributes={"score"=>"1", "class"=>"Algebra",
"student_id"=>"1", "id"=>"1"}>]

之所以可以动态的在关系声明时添加方法是因为当调用grade()方法时返回的是ActiveRecord::Associations::AssociationProxy实例他介于这里是Student 和Grade 之间 真正的例如 find( ), count( ), create( )方法都是在关系(如has_many)定义的,这个关系的调用返回的是一个代理再由这个代理执行具体的mode的方法 (find( ), count( ), create( )...),因此可以在关系中扩展方法。就像继承扩展一样


分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics