1

По умолчанию: completed_at is nil. Если я использую полный метод, то complete_at превращается во Time.now. Я проверил его, и все получилось. Несмотря на это мой запрос не работает в случае входящих/исходящих задач. Что действительно странно, что запрос отлично работает с завершенными задачами. Так что «где» запрос не работает, но «where.not» делает. Можете ли вы мне помочь?условный активный запрос записи с рельсами

def incoming_tasks 
    @user =current_user 
    @executed_tasks = @user.executed_tasks.where("completed_at = ?", 'nil').order("created_at DESC") 
end 

def outgoing_tasks 
    @user = current_user 
    @assigned_tasks = @user.assigned_tasks.where("completed_at = ?", 'nil').order("created_at DESC") 
end 

def completed_tasks 
    @user = current_user 
    @assigned_tasks = @user.assigned_tasks.where.not("completed_at = ?", 'nil').order("completed_at DESC") 
    @executed_tasks = @user.executed_tasks.where.not("completed_at = ?", 'nil').order("completed_at DESC") 
end 

Вот как я сделал completed_at атрибут, имеющей дату:

def complete 
    @task = Task.find(params[:id]) 
    @task.update_attribute(:completed_at, Time.now) 
    redirect_to completed_tasks_user_tasks_path(current_user) 
end 
+0

SQL обычно использует ключевое слово 'IS', чтобы определить, имеет ли значение значение null, см. Http://stackoverflow.com/questions/1833949/why-is-null-not-equal-to-null-false. – bdares

ответ

2

Как отметил выше, вам нужно сгенерировать SQL с IS ключевым словом, чтобы определить, является ли столбец NULL. Вместо того, чтобы препирать это самостоятельно, вы можете передать хэш до where и позволить ActiveRecord обрабатывать тонкости; i.e:

def incoming_tasks 
    @user =current_user 
    @executed_tasks = @user.executed_tasks.where(completed_at: nil).order("created_at DESC") 
end 

def outgoing_tasks 
    @user = current_user 
    @assigned_tasks = @user.assigned_tasks.where(completed_at: nil).order("created_at DESC") 
end 

def completed_tasks 
    @user = current_user 
    @assigned_tasks = @user.assigned_tasks.where.not(completed_at: nil).order("completed_at DESC") 
    @executed_tasks = @user.executed_tasks.where.not(completed_at: nil).order("completed_at DESC") 
end 

Как в стороне, это будет отличное место для использования области.

Edit для деталей:

(Оговорка:.. SQL является спецификация, а не реализация, а SQL генерируется рельсам зависит от адаптера базы данных Следующие действия могут варьироваться в зависимости от вашего выбора базы данных)

Ok, несколько вещей:

  1. Вы с помощью where("completed_at = ?", 'nil'), которая на самом деле ищет записи, где completed_at является строка"nil". Это почти наверняка не то, что вы хотите, и имеет другие непредвиденные последствия.

  2. SQL имеет особый способ обработки значений NULL, когда речь идет о соответствующих строках. При использовании оператора = в предложении WHERE он будет игнорировать строки с значениями NULL. Вы должны использовать один из операторов IS NULL или IS NOT NULL, чтобы рассуждать о значении NULL.

Рассмотрим таблицу:

| id | completed_at    | 

| 1 | 2015-07-11 23:23:19.259576 | 
| 2 | NULL      | 

С помощью следующих запросов:

Rails        | SQL        | Result 

where("completed_at = ?", 'nil')  | WHERE (completed_at = 'nil')  | nothing, since completed_at isn't even a string 
where.not("completed_at = ?", 'nil') | WHERE (NOT (completed_at = 'nil')) | only row 1, since = can't match a NULL value, even when negated 
where("completed_at = ?", nil)  | WHERE (completed_at = NULL)  | nothing, you can't test for NULL with the = operator 
where.not("completed_at = ?", nil) | WHERE (NOT (completed_at = NULL)) | nothing, you can't test for not NULL with = either 
where(completed_at: nil)    | WHERE completed_at IS NULL   | row 2 only 
where.not(completed_at: nil)   | WHERE (completed_at IS NOT NULL) | row 1 only 

Конечно, where(completed_at: nil) это просто сокращение для where('completed_at IS NULL'), и то же самое для его обратное, но хэш формат более идиоматичен и не зависит от адаптера базы данных.

Магическая часть всего этого заключается в том, что ActiveRecord может определить, следует ли использовать = или IS NULL, посмотрев на хэш, который вы передаете на номер where. Если вы передадите фрагмент, он понятия не имеет, поэтому он применяет его вслепую.

+0

Можете ли вы рассказать мне, почему это сработало с где. Не и почему не с чего? Я попытаюсь использовать область действия. Если я застрял с ним, я спрошу вас, как это сделать.Thx –

+0

Спасибо за понимание. В этой таблице было совершенно ясно. –

+0

Добро пожаловать. Пожалуйста, примите мой ответ, если вы удовлетворены. – ahmacleod

Смежные вопросы