Ваша проблема здесь:
def self.from_users_followed_by(user)
following_ids = user.following_ids
where("user_id IN (#{following_ids}) OR user_id = ?", user)
#------------------^^^^^^^^^^^^^^^^
end
Ваш following_ids
будет массивом, и когда вы "#{array}"
, вы получите такие вещи, как []
и [11, 23, 42]
.Таким образом, where
будет выглядеть примерно так:
where("user_id IN ([]) OR user_id = ?", user)
where("user_id IN ([11, 23, 42]) OR user_id = ?", user)
, ни один из них не содержит допустимого SQL.Некоторые базы данных могут игнорировать случайные скобки, но PostgreSQL этого не сделает.
Вам необходимо внести два изменения:
- Не включать
user_id IN (...)
вообще, если following_ids
пусто,Выполнение c in ()
не является допустимым SQL, поэтому вы не хотите этого делать.Опять же, некоторые базы данных мягки и снисходительны, PostgreSQL (к счастью) не относится ни к одной из этих вещей. - Не используйте простую интерполяцию строк для предоставления значений для вашего
IN
;в этом отношении, вообще не используйте строковую интерполяцию для своего SQL (если нет абсолютно никакого другого пути, и это редко): мы не пишем PHP в 1999 году, мы должны знать лучше сейчас.К счастью для вас (и для всех нас), AR сделает все правильно, если вы передадите ему массив для значения заполнителя.
Примерно так должно работать лучше:
def self.from_users_followed_by(user)
following_ids = user.following_ids
if(following_ids.empty?)
where('user_id = ?', user)
else
where('user_id in (?) or user_id = ?', following_ids, user)
end
end
Вы также можете сделать это так:
def self.from_users_followed_by(user)
following_ids = user.following_ids
if(following_ids.empty?)
where('user_id = ?', user)
else
following_ids.push(user.id)
where('user_id in (?)', following_ids
end
end
или, мой любимый, вот так:
def self.from_users_followed_by(user)
where('user_id in (?)', user.following_ids + [user.id])
end