ActiveRecord::StatementInvalid SQLite3::SQLException: нет такого столбца: true:

Я хочу получить @messages return @folder.messages, где значение столбца "удалено" НЕ равно true. Я не уверен, почему это вызывает исключение SQLException. Я предполагаю, что я не форматирую удаленный атрибут должным образом, но я не уверен, как это исправить.

Любая помощь будет принята с благодарностью. Заранее спасибо.

Сообщение об ошибке:

ActiveRecord::StatementInvalid in MailboxController#index  
SQLite3::SQLException: no such column: true: SELECT     "message_copies".* FROM       "message_copies"  WHERE     ("message_copies".folder_id = 1) AND (deleted != true)  

Трассировка приложения:

app/controllers/mailbox_controller.rb:14:in `show'  
app/controllers/mailbox_controller.rb:5:in `index'  

Mailbox_Controller.rb

1   class MailboxController < ApplicationController  
2     def index  
3       current_user = User.find(session[:user_id])  
4       @folder = Folder.where("user_id = #{current_user.id}").first  
5       show  
6       render :action => "show"  
7     end
8  
9     def show  
10      current_user = User.find(session[:user_id])  
11      @folder = Folder.where("user_id = #{current_user.id}").first  
12      @msgs = @folder.messages  
13      @ms = @msgs.where("deleted != true")  
14      @messages = @ms.all.paginate :per_page => 10,  
15                 :page => params[:page], :include => :message,  
16                 :order => "messages.created_at DESC"  
17    end  
18  end  

3 ответа

Решение

SQLite использует логические значения в стиле C:

SQLite не имеет отдельного булева класса хранения. Вместо этого логические значения хранятся как целые числа 0 (ложь) и 1 (истина).

Итак, когда вы говорите это:

deleted != true

SQLite не знает что true так что предполагается, что вы пытаетесь сослаться на другое имя столбца.

Правильный способ справиться с этим - позволить AR преобразовать ваш логический Ruby в логический SQLite (как в ответах Tam и fl00r). Я думаю, что полезно знать, что ты делаешь неправильно, хотя.

ОБНОВЛЕНИЕ: если вы хотите проверить не верно deleted и включите NULL, тогда вы захотите это:

@ms = @msgs.where("deleted != ? OR deleted IS NULL", true)

Или лучше не допускать NULL в deleted совсем. Вы не должны допускать, чтобы NULL представлял собой любой столбец, кроме случаев, когда это абсолютно необходимо (значение по умолчанию для ActiveRecord для обнуляемости в точности противоположно тому, что должно быть). SQL NULL - странный зверь, и вы всегда должны обращаться с ним особым образом, лучше всего не допускать его, если вам не нужно значение "не там" или "не указано" для столбца.

@ms = @msgs.where("deleted != ?", true) 
# OR
@ms = @msgs.where(:deleted => false) 

true отличается для разных баз данных. В некоторых это t/f значение, а в некоторых true/false, поэтому вы должны или поместить его в кавычки и быть уверенным, подходит ли он для вашей конкретной базы данных, или вы должны исключить его из вашего sql, чтобы Rails выполнил эту работу за вас.

UPD

Если deleted является NULL, Первый. Установить удаленное поле как ложное по умолчанию. Во-вторых, как найти его с помощью AR:

@ms = @msgs.where("deleted = ? OR deleted = ?", false, nil)
# wich won't work, Thanks to @mu is too short
@ms = @msgs.where("deleted = ? OR deleted IS NULL", false)

Пытаться

@ms = @msgs.where(["deleted != ?",true])
Другие вопросы по тегам