诗歌rails之嵌套使用rails find :include选项

在Rails的API里,find方法有如下参数,conditions order group having limit offset joins include select from readonly lock

   其中,对于include的解释是说,include选项后的参数,应该是一个已经关联的表。该表信息会在检索后,和检索表信息一起加载。给的例子如下:

Irb代码
  1. Person.find(:all, :include => [ :account, :friends ])  


   include选项的好处就不举例说了,其实,就和你用游标做全检索,还是join出一个view一个道理。

    现在说下面一个情况,有学生表和班级表如下:
Irb代码
  1. class Class < ActiveRecord::Base  
  2.     has_many :students  
  3. end  
  4.   
  5. class Student < ActiveRecord::Base  
  6.     belongs_to :class  
  7. end  

   
    很显然,当我们要输出所有学生的班级信息时,我们会用include如下:
Irb代码
  1. Student.find(:all,:include => [:class], :conditions =>["user_name = ?", user_name])  

    然而,当我们的要求增加,有一个新的表学校信息也希望检索出来时,那么,表结构如下:
Irb代码
  1. class University < ActiveRecord::Base  
  2.          has_many :class  
  3. end  
  4. class Class < ActiveRecord::Base  
  5.          has_many :students  
  6.          belongs_to :university  
  7. end  
  8.   
  9. class Student < ActiveRecord::Base  
  10.     belongs_to :class  
  11. end  

     那当我们想要输出所有学生的学校相关信息时,那么,也许我们会想到使用检索语句
Irb代码
  1. Student.find(:all,:include => [:class,:university], :conditions =>["student_name = ?", student_name])  

     实际上,运行结果是,我们会得到一个':university' is not a valid association of the Student model的错误提示。

      这个错误提示,是可以理解的。正如,文章开始的Rails API里所说的include后面的参数应该是一个已经和检索表有关联的表。实际上University和Student表没有直接关联。这时的惯性思维是使用find_by_sql,诚然,的确可以解决。其实,应该嵌套include选项。

      那么,解决这个问题需要用到through参数。更新表结构如下:
Irb代码
  1. class University < ActiveRecord::Base  
  2.          has_many :class  
  3. end  
  4.   
  5. class Class < ActiveRecord::Base  
  6.          has_many :students  
  7.          belongs_to :university  
  8. end  
  9.   
  10. class Family < ActiveRecod::Base  
  11.          has_many :students   
  12. end  
  13.   
  14. class Student < ActiveRecord::Base  
  15.     belongs_to :class  
  16.          belongs_to :university, :through => :class  
  17.          belongs_to :family  
  18. end  

      执行检索语句:
Irb代码
  1. Student.find(:all,:include => [{:university=>:class},:family], :conditions =>["student_name = ?", student_name])  


请注意其中嵌套部分的使用。

(本文参考:http://snippets.dzone.com/posts/show/2089)
posted @ 2009-08-13 20:09  麦飞  阅读(1306)  评论(0编辑  收藏  举报