Не равно условному

Я хочу иметь предложение where с равным и не равным условием:

@user = User.where(:user_id => current_user.id, :author_id != current_user.id).nil? ? (render :something) : (render :somethingelse)

Вышеупомянутое не работает:

синтаксическая ошибка, неожиданное ')', ожидание tASSOC ...d, :user_id != current_user.id).nil? ? (рендеринг :индекс) : (ре...

Однако если я изменю второе условие с != на =>, оно сработает.

Как мне иметь оба условия в одном классе? Спасибо


person user715697    schedule 14.05.2011    source источник
comment
@taro На этой неделе я закончил Учебное пособие по Ruby on Rails: изучаем Rails на примерах, но оно не охватило такие условные выражения, поэтому я все еще учусь. Также было предложено начать с Rails, прежде чем переходить на Ruby. Но спасибо за ваш отзыв.   -  person user715697    schedule 14.05.2011
comment
вы должны использовать empty? вместо nil?, потому что where возвращает массив как таковой.   -  person konyak    schedule 28.01.2015


Ответы (6)


Вот как можно использовать Arel для создания запроса «select * from users where user_id = ? and author_id != ?»:

users = User.arel_table
User.where(users[:user_id].      eq(current_user.id).and(
           users[:author_id].not_eq(current_user.id)))

Использование Arel не так лаконично, как использование условий Hash для простых условий, но оно намного мощнее!

Вот ссылка на полный список предикатов (eq, not_eq, gt, lt и т. д. ) доступно с Arel.

person Tyler Rick    schedule 07.06.2012
comment
Этот ответ лучше, потому что он больше не зависит от базы данных. Например, некоторые базы данных не понимают !=, а другие понимают. - person maletor; 27.08.2013

Я считаю, что это должно быть:

@user = User.where(['user_id = ? AND author_id <> ?', current_user.id, current_user.id])
render(@user ? :something : :somethingelse)
person taro    schedule 14.05.2011
comment
Спасибо, это тоже сработало. Думаю, я не могу получить все это в одной строке, используя .nil? как я и надеялся :) - person user715697; 14.05.2011

В Rails 4 все это просчитано

Model.where.not(:colname => nil)
#=> returns all records whose :colname values are not nil
person boulder_ruby    schedule 12.11.2013

Синтаксическая ошибка возникает из-за того, что вы пытаетесь использовать != вместо =>. Метод where не поддерживает неравенство с хешированными аргументами, поэтому вам нужно будет записать не равно, используя аргументы массива.

User.where(:user_id => current_user.id).where(['users.author_id <> ?', current_user.id])
person Douglas F Shearer    schedule 14.05.2011
comment
Спасибо Дуглас. Есть ли способ использовать :author_id вместо литерала в кавычках? (не то чтобы это важно, просто интересно) - person user715697; 14.05.2011
comment
Единственное предложение, которое я мог бы добавить к этому, - это посмотреть на meta_where, который на самом деле поддерживает синтаксис, очень похожий на то, что вы разместили в своем вопросе. github.com/ernie/meta_where - person Douglas F Shearer; 14.05.2011
comment
Вы также можете использовать :author_id вместо строки, если используете Arel (см. мой ответ ниже)... - person Tyler Rick; 07.06.2012

http://guides.rubyonrails.org/active_record_querying.html#hash-conditions

С условиями хеширования возможна только проверка на равенство, диапазон и подмножество.

Вам нужно либо перейти к прямому SQL, либо инвертировать и задать запрос, см. Есть ли способ инвертировать запрос ActiveRecord::Relation?

person Jonah    schedule 14.05.2011

Не уверен, знаете ли вы, что условие не равно обычно не соответствует значениям NULL (author_id). Вам придется сделать OR author_id IS NULL, если вы этого хотите.

@users = User.where("user_id = ? AND (author_id != ? OR author_id IS NULL)", 
                    current_user.id, current_user.id)

render(@users.present? ? :something : :somethingelse)

Также обратите внимание, что я использую @users.present?, потому что where finder возвращает массив ActiveRecord::Relation.

person konyak    schedule 27.01.2015