2012-02-27 80 views
1

我有一個函數需要編寫,但無法計算出它的工作方式。第一行按照它們應該的順序返回我的步驟,第二行我想返回課程所有步驟中的最後一個匹配步驟。我認爲我很接近,但需要知道我做錯了什麼。找到集合的最後匹配記錄

course_steps_in_order = course.steps.sort_by(&:component_and_step_order)  
last_completed_step = current_user.completed_steps.where("steps.id in ?", course_steps_in_order).last 

我收到錯誤...

ActiveRecord::StatementInvalid: PG::Error: ERROR: syntax error at or near "1" 
LINE 1: ... WHERE "user_steps"."user_id" = 3 AND (step.id in 1,2,4,8,5,... 
                 ^
: SELECT "steps".* FROM "steps" INNER JOIN "user_steps" ON "steps"."id" = "user_steps"."step_id" WHERE "user_steps"."user_id" = 3 AND (step.id in 1,2,4,8,5,3,7,6,9) ORDER BY "steps"."id" DESC LIMIT 1 

的課程有很多組成部分,其具有許多步驟,按以下型號...

class Course < ActiveRecord::Base 
    has_many :components, :dependent => :destroy, :order => "component_order" 
    has_many :steps, :through => :components, :dependent => :destroy 
end 

class Component < ActiveRecord::Base 
    belongs_to :course 
    has_many :steps, :dependent => :destroy, :order => "step_order" 
end 

class Step < ActiveRecord::Base 
    belongs_to :component 

    def component_and_step_order 
    component_order * 100 + step_order 
    end 
end 

回答

2

添加收藏 - 括起括號:

... 
last_completed_step = current_user.completed_steps.where("steps.id in (?)", course_steps_in_order).last 

現在查詢將正確地產生像這樣:

... AND (step.id in (1,2,4,8,5)) 
3

你有兩個問題:一是你知道,一個你不知道。第一個也是最明顯的問題是clyfe已經解決了你的SQL語法錯誤。第二個問題是,IN不保證任何特定的順序,使這樣的:

current_user.completed_steps.where("steps.id in (?)", course_steps_in_order).last 

不能保證給你的最後一步,其idcourse_steps_in_order和甚至不保證從一個執行產生相同的結果下一個。如果您想以特定順序從SQL中獲取結果,則您必須使用ORDER BY子句明確指定該順序,您需要必須。舉例來說,我只是在我的PostgreSQL表之一做:

=> select id from some_table where id in (1,2,3,4,5); 
id 
---- 
    1 
    5 
    2 
    3 
    4 

你的方法會給你4作爲最後一個時,你會期待5

請允許我重複一遍:關係數據庫的基礎設置和固有無序的,如果你需要在一個特定的順序東西,那麼你必須明確指定ORDER BY子句的順序。

如果你希望你的last調用意味着什麼有用的東西,那麼你需要你的component_and_step_order方法轉換爲.order呼叫,包括在你的current_user.completed_steps.where查詢。

+0

我在模型中通過:order =>「step/component_order」調用在模型中命令它們。這是我想要的順序,而不是編號。這會解決您所談論的問題嗎? – Norto23 2012-02-28 01:05:13

+0

@ bouser1188763:'current_user.completed_steps'是否包含任何地方的「訂單」調用?如果沒有,那麼你有問題。不管你在模型中做什麼,你都假定in(2,1,3)'會以2-1-3的順序返回行,但是這個假設是無效的。 – 2012-02-28 01:23:25

+0

是的,我現在看到,它確實按照它們的創建時間排序,所以當它們被迫按順序逐步完成時,這將工作(我認爲)。用戶has_many:user_steps,:dependent =>:destroy do def for_course(course) joins(:step => {:component =>:course})。where(「courses.id =?」,course)。order(「created_at」) end end 然後用戶還有 - > has_many:completed_steps,:through =>:user_steps,:source =>:步驟 – Norto23 2012-02-28 01:30:53