ActiveRecord :: StatementInvalid SQLite3 :: SQLException: нет такого столбца: true: - PullRequest
7 голосов
/ 24 апреля 2011

Я хочу получить @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 ]

18 голосов
/ 24 апреля 2011

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

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

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

deleted != true

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

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

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

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

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

3 голосов
/ 24 апреля 2011
@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)
0 голосов
/ 24 апреля 2011

попробуй

@ms = @msgs.where(["deleted != ?",true])
...