“No such column” error when using following_ids map on Rails Turorial - may be caused by array square brackets?

StackOverflow https://stackoverflow.com/questions/8874614

  •  28-10-2019
  •  | 
  •  

Вопрос

I'm attempting to complete section 12.3 of the railstutorial.org tutorial.

At the beginning of section 12.3, my rspec tests were passing and the site worked. However, after adding the listing in section listing 12.42, a large number of previously-passing tests started failing. (As part of my error checking, I tried copying and pasting the code directly from the tutorial site, with the same result.) I attempted to open the site on localhost, and found the tests were failing because the home page was returning an exception:

SQLite3::SQLException: no such column: 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51: SELECT "microposts".* FROM "microposts" WHERE (user_id IN ([2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51]) OR user_id = 1) ORDER BY microposts.created_at DESC LIMIT 30 OFFSET 0

Rails.root: /Users/paulbogard/Sites/sample_app

The code that seems to be generating that exception is in my app/models/micropost.rb:

class Micropost < ActiveRecord::Base
  attr_accessible :content

  belongs_to :user

  validates :content, :presence => true, :length => { :maximum => 140 }
  validates :user_id, :presence => true

  default_scope :order => 'microposts.created_at DESC'

  def self.from_users_followed_by(user)
    following_ids = user.following_ids
    where("user_id IN (#{following_ids}) OR user_id = ?", user)
  end
end

Playing around with it, it seems like it doesn't like the square brackets surrounding the array of following_ids. For example, changing the where line to this simplified magic number version also generates the "no such column" error:

where("user_id IN ([2, 3, 4]) OR user_id = ?", user)

But if I change it to the following, I don't get the error:

where("user_id IN (2, 3, 4) OR user_id = ?", user)

And, in fact, using the no-square-bracket version has all tests passing except for the ones specifically checking that it's returning posts from followed users and not returning posts from unfollowed users (as I'd expect by just tossing magic numbers into the SQL query).

So it appears the square brackets seem to be making SQLite think that what's included is a column name. Is there a way to rewrite the following_ids = user.following_ids line so that I get a string of array values without square brackets? Or should I be doing something else entirely?

Это было полезно?

Решение

Just let ActiveRecord include the array into your query. That way, it handles the formatting and even the eventual escaping.

def self.from_users_followed_by(user)
  following_ids = user.following_ids
  where("user_id IN (?) OR user_id = ?", following_ids, user)
end
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top