2013-05-10 31 views
2

編輯 - 使用'includes'生成SQL'IN'子句。使用Oracle時,這有1000個項目的限制。它不適用於我的公司。那裏有其他解決方案嗎?Rails - 協會上的急切加載協會

是否有可能急於加載關聯關聯?

例如,假設我有一個學院課程,並且學院有很多學生。每個學生belongs_to的student_level

class Academy < ActiveRecord::Base 
    has_many :students 
end 

class Student < ActiveRecord::Base 
    belongs_to :academy 
    belongs_to :student_level 
end 

class StudentLevel < ActiveRecord::Base 
    has_many :students 
end 

是否可以定製協會學院,這樣,當我加載學生,我總是加載與學生的student_level?

換句話說,我想下面的代碼段,以產生一個或兩個查詢總數,而不是一個查詢爲每一個學生:

@academy.students.each do |student| 
    puts "#{student.name} - #{student.student_level.level_name}" 
end 

我知道,如果我改變學生從我能做到這一點關聯到一種方法,但我不想這樣做,因爲我無法在其他查詢中將學生作爲關聯參考。我也知道我可以通過以下方式在SQL中執行此操作,但是我想知道在沒有finder_sql的情況下是否有辦法在我的關聯中執行此操作,因爲現在我需要隨時更新我的​​finder_sql,而我的默認範圍發生更改,無法預加載關聯:

SELECT students.*, student_levels.* FROM students 
LEFT JOIN student_levels ON students.student_level_id = student_levels.id 
WHERE students.academy_id = ACADEMY_ID_HERE 

回答

5

您是否嘗試過使用includes來加載數據?

class Academy < ActiveRecord::Base 
    has_many :students 

    # you can probably come up with better method name 
    def students_with_levels 
    # not sure if includes works off associations, see alternate below if it does not 
    self.students.includes(:student_level) 
    end 

    def alternate 
    Student.where("academy_id = ?", self.id).includes(:student_level) 
    end 
end 

還看到:http://guides.rubyonrails.org/active_record_querying.html#eager-loading-associations

應導致3查詢

  • 上學院的初始查找
  • 對學生的集合的查詢對象
  • 查詢所有的那些學生StudentLevel對象

加法:

# the same can be done outside of methods 
@academy.students.includes(:student_level).each do |student| 
    puts "#{student.name} - #{student.student_level.level_name}" 
end 

Student.where("academy_id = ?", @academy.id).includes(:student_level).each do |student| 
    puts "#{student.name} - #{student.student_level.level_name}" 
end 

ActiveRelation查詢也可鏈接

@academy.students_with_levels.where("name ILIKE ?", "Smi%").each do # ... 

排序上的ActiveRecord查詢封裝相關的一個很好的文章(方法) - http://ablogaboutcode.com/2012/03/22/respect-the-active-record/

+0

在我原來的問題:「我知道如果我將學生從一個協會轉變爲一種方法,我可以做到這一點,但我不想這樣做,因爲我無法將學生作爲我的協會參考其他查詢「。也許這是做到這一點的唯一方法。 – Dave 2013-05-12 12:02:29

+0

添加了「添加」部分,您不僅限於使用activerecord方法內部的包含技術 – house9 2013-05-12 14:24:18

+0

謝謝,我認爲這將起作用 – Dave 2013-05-13 15:46:29