2011-10-07 72 views
1
# student.rb 
has_and_belongs_to_many :courses 

# course.rb 
has_and_belongs_to_many :students 

我試圖在學生模型中創建一個範圍,以檢查它們是否註冊了課程。Rails 3.1 - 使用示波器查找未註冊的學生

我想出的最好的是:

scope :unenrolled, where(Student.courses.count => 0) 

但後來我得到錯誤信息

undefined method `courses'

任何人提供任何建議?

回答

5

好吧。因此,這裏是你的代碼:

scope :unenrolled, where(Student.courses.count => 0) 

這裏的第一個問題是,這是造成錯誤的事情:你調用實例方法coursesStudent類。顧名思義,您只能在類的實例上調用實例方法,而不能在類本身上調用。例如:

jim = Student.find(123) 
jims_courses = jim.courses 

但這裏的踢球:當你打電話scope你在方面,即代碼不是一個實例方法裏面,所以當你的模型首次宣佈它被調用。當時沒有實例,因此您不能像從Student的實例方法之一中調用courses那樣。

但是,這是有點沒有意義,因爲你有點誤解where如何工作。您給where的參數應該是條件,它們對應於您在SQL查詢中將WHERE後放置的內容。例如,where(:eye_color => 'brown')將變成SQL WHERE子句,如WHERE eye_color = 'brown':eye_color => 'brown'只是一個Hash與密鑰:eye_color其值是'brown'。調用=>左側的函數是沒有意義的,除非該函數返回模型中ActiveRecord將理解的列/屬性的名稱。

所以現在讓我們來看看你應該做什麼。如果你正在寫一個SQL查詢它會是這個樣子:

SELECT `students`.*, COUNT(`courses_students`.*) AS `courses_count` 
    FROM `students` 
    JOIN `courses_students` ON `students`.`id` = `courses_students`.`student_id` 
WHERE `courses_count` = '0' 
GROUP BY `courses_students`.`student_id`; 

這大致翻譯成一個ActiveRecord這樣的查詢: Student.joins(:課程)。 // AR自動加入courses,但courses_students select('students。,COUNT(courses。)AS courses_count')。 其中('courses_count = 0')。 組(「ID」)

,您可以直接花掉那到你的範圍:

scope :unenrolled, joins(:courses). 
        select('students.*, COUNT(courses.*) AS courses_count'). 
        where('courses_count = 0'). 
        group('courses.course_id') 

注:這些查詢是有點過的,袖口,可能需要一些調整。構建複雜的ActiveRecord查詢最簡單的方法是直接將它們輸入到Rails控制檯,直到獲得所需的結果。

希望有幫助!

+0

現在這就是爲什麼我喜歡SO社區!非常感謝幫助,我比以前更瞭解這一點! 我可以看到查詢中的邏輯,但它仍然拋出異常。 'SQLite3 :: SQLException:no such column:courses.course_id:SELECT COUNT(*)AS count_all,courses.course_id AS courses_course_id FROM「students」INNER JOIN「courses_students」ON「courses_students」。「student_id」=「students」 。「id」INNER JOIN「courses」ON「courses」。「id」=「courses_students」。「course_id」WHERE(courses_count = 0)GROUP BY courses.course_id ORDER BY「students」.id desc ' – Ammar

+0

SQL isn '我的東西真的:( – Ammar

+0

對不起,最後一行應該是'group('courses.id')'。 –