簡體   English   中英

使用Rails的條件活動記錄查詢

[英]conditional active record query with rails

默認情況下:completed_at為零。 如果我使用complete方法,則completed_at變為Time.now。 我檢查了一下,效果很好。 盡管如此,在傳入/傳出任務的情況下,我的查詢無法正常工作。 真正奇怪的是,查詢與已完成的任務完美配合。 因此,“ where”查詢不起作用,而“ 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

如上所述,您需要使用IS關鍵字生成SQL以確定列是否為NULL 您可以自己將哈希傳遞到where並讓ActiveRecord處理細微差別,而不必自己弄亂它。 即:

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

順便說一句,這將是使用示波器的好地方。

編輯詳細信息:

(注意:SQL是一個規范,而不是實現,並且rails生成的SQL取決於數據庫適配器。以下內容可能會因您選擇的數據庫而異。)

好的,幾件事:

  1. 您使用的是where("completed_at = ?", 'nil') ,它實際上是在查找completed_at字符串 "nil" 幾乎可以肯定這不是您想要的,並且會帶來其他意想不到的后果。

  2. 當涉及到匹配行時,SQL有一種處理NULL值的非常特殊的方式。 WHERE子句中使用=運算符時,它將忽略具有NULL值的行。 您必須使用IS NULLIS 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可以通過查看傳遞給where的哈希值來確定它應該使用=還是IS NULL 如果傳遞片段,則毫無頭緒,因此會盲目地應用它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM