条件添加parantheses导致语法错误的Rails

时间:2014-09-25 20:26:09

标签: ruby-on-rails

我在mysql中创建了我想要的确切查询,工作正常:

SELECT 
    tasks.* 
FROM
    tasks 
    INNER JOIN 
        leads
        ON leads.id = tasks.taskable_id AND tasks.taskable_type = "Lead"
WHERE 
    tasks.taskable_id IN (1, 2) 
    AND 
    (
        tasks.id = 
        (
            SELECT tasks.id 
            FROM tasks
            WHERE tasks.taskable_id = leads.id 
            AND
            tasks.taskable_type = "Lead"
            AND 
            appointment_status = 1
            ORDER BY created_at asc
            LIMIT 1
        )
    )

我花了两个多小时尝试将其翻译成ActiveRecord语法,但我无法让它工作。我得到的最接近的是:

Task.joins(:lead_tasks)
    .where(
        taskable_id: self.all.map(&:id)
    )
    .where(
        "tasks.id = (?)",
        Task.select(:id)
                .where("tasks.taskable_id = (?) AND tasks.taskable_type = ?", self.where(appointment_status: APPOINTMENT_STATUS[:yes]).map(&:id), "Lead")
                .order('created_at asc')
                .limit(1)
     )

  class Task
  belongs_to :lead_tasks, -> { where(tasks: { taskable_type: "Lead"}) },foreign_key: :taskable_id, class_name: "Lead"

但这会生成如下所示的SQL:

SELECT `tasks`.* FROM `tasks` 
INNER JOIN `leads` ON `leads`.`id` = `tasks`.`taskable_id` 
AND 
`tasks`.`taskable_type` = 'Lead' 
WHERE `tasks`.`taskable_id` IN (1, 2) 
AND 
(tasks.id = (SELECT  `tasks`.`id` FROM `tasks`  WHERE (tasks.taskable_id = (1,2) 
AND tasks.taskable_type = 'Lead')  ORDER BY created_at asc LIMIT 1));

区别在于Rails在WHERE之后添加了extra()导致以下语法错误:

Mysql2::Error: Operand should contain 1 column(s)

如何强制Rails不添加()?或者更好的是,在Rails中构建这个子查询的正确方法是什么?

1 个答案:

答案 0 :(得分:0)

我得到了这样的工作:

sql = Task.select(:id).where("tasks.taskable_id = leads.id AND tasks.taskable_type = 'Lead' AND appointment_status = 1").order("created_at asc").limit(1).to_sql
Task.joins(:lead_tasks).where(taskable_id: self.all.map(&:id)).where("tasks.id = (#{sql})")

这将返回我需要的任务对象的ActiveRecord关系。