2012-02-27 79 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