рельсы 3, где вложенные условия - PullRequest
0 голосов
/ 25 марта 2012

Хорошо, у меня есть это

User.find(4).friends

 [#<Contact id: 67, type: nil, default_contact_group: false, primary_contact_id: nil, invitation_code: nil, flag_for_review: true, code_name: nil, reset_password_token: nil,  
.......
.......

User.find(4).friends.count
 => 5 

User.find(4).friends.map(&:type)
 => [nil, nil, nil, nil, nil] 

как вы можете видеть, все поля типа равны нулю, но когда я делаю это, где предложение я всегда ничего не возвращаю

 User.find(4).friends.where("type != 'ContactGroup'")
 => [] 

 User.find(4).friends.where(["type != ?", "ContactGroup"])
 => [] 

что я делаю не так и почему он не возвращает записи, которые явно совпадают

Ответы [ 3 ]

2 голосов
/ 25 марта 2012

Я предполагаю, что значения столбца type в вашей базе данных на самом деле NULL.

Тогда вы теперь наблюдаете интересный аспект значения NULL.Результат сравнения NULL с другим значением не равен ни TRUE, ни FALSE, а UNKNOWN.Таким образом, в вашей базе данных сравнение значения с NULL никогда не бывает верным, и обратное никогда не бывает верным.Вот почему вы не видите результатов в своем последнем запросе.

Чтобы смягчить это, есть специальный оператор сравнения: IS NULL и IS NOT NULL.Вы можете использовать его с рельсов, как это:

User.find(4).friends.where(["type != ? or type IS NOT NULL", "ContactGroup"])
1 голос
/ 25 марта 2012

friends уже является массивом и будет отвечать на .select.

User.find(4).friends.select {|f| f.type != 'ContactGroup'}

# Or .reject
User.find(4).friends.reject {|f| f.type == 'ContactGroup'}
0 голосов
/ 25 марта 2012

Не следует использовать имя столбца type из-за того, как Rails реализует наследование одной таблицы. Эта статья объясняет более подробно .

Это все еще применимо к Rails 3. В консоли Rails 3 я получаю эту ошибку при попытке выполнить те же действия, что и вы.

ActiveRecord :: SubclassNotFound: механизм наследования одной таблицы не удалось найти подкласс: «тест». Эта ошибка возникает потому, что столбец type зарезервирован для хранения класса в случае наследование. Пожалуйста, переименуйте этот столбец, если вы не хотели используется для хранения класса наследования или перезаписи VideoFile.inheritance_column, чтобы использовать другой столбец для этого информация.

...