2012-08-28 22 views
1

我有一个包含多个比赛和对象的设置。他们与has_many并列在一起:通过与contest_objs的安排。 contest_objs也有选票,所以我可以有几个比赛,包括几个对象。我有一个复杂的SQL设置来计算当前排名。但是,我需要在排序的SQL select语句中指定比赛。我很难做到这一点。这是我走到这一步:将变量插入复杂的sql命令

@objects = @contest.objects.select('"contest_objs"."votes" AS v, name, "objects"."id" AS id, 
            (SELECT COUNT(DISTINCT "oi"."object_id") 
              FROM contest_objs oi 
              WHERE ("oi"."votes") > ("contest_objs"."votes"))+1 AS vrank') 

是否有vrank的选择任何方式指定WHERE还包括“OI”“contest_id” = @ contest.id?

回答

3

由于@ contest.id是一个整数,不存在SQL注入的任何风险,你可以做以下使用字符串插值:

Model.select("..... WHERE id = #{@contest.id}") 

另一种可能的解决办法是建立使用ActiveRecord的子查询,然后调用.to_sql以获取生成的SQL,并将其插入到主查询中。

+0

我已经试过了,它给我这个错误'ActiveRecord :: StatementInvalid(SQLite3 :: SQLException:无法识别的令牌:“#”' – Marc

+0

你确定你使用双引号吗?不能使用单引号。 – Intrepidd

+0

呵呵。有效。我一直认为单引号和双引号是可以互换的。有用! – Marc

-1

您可以变量插入到SQL命令是这样的:

Model.select("...... WHERE id = ?", @contest.id) 

Rails会逃跑的值给你。

编辑:

中发表的意见Intrepidd说这不行,用串插就像他在他的回答提出。整数参数是安全的。

如果你发现自己在查询中插入了几个字符串,你可以考虑使用find_by_sql,它给你上面提到的?替换,但是你不能在链接中使用它,所以需要重写整个查询。

+1

错误。选择只接受一个参数并且不会转义参数。它将在哪里但不选择。 你会得到以下错误:ArgumentError:错误的参数数目(2为1) – Intrepidd

+0

感谢您的澄清,但他可以使用[find_by_sql](http://api.rubyonrails.org/classes/ActiveRecord/Querying .html#method-i-find_by_sql),对吗? – Felix

+0

的确,但他必须编写整个SQL查询。 – Intrepidd