I am getting a 500 error when I try to deploy my app to Heroku (it works fine on my localhost). Not sure why this is happening.
How can I fix it? Error details are below…
Error Details
2012-01-03T10:33:49+00:00 app[web.1]: Started GET "/" for
2012-01-03T10:33:49+00:00 app[web.1]: Processing by PagesController#home as HTML
2012-01-03T10:33:49+00:00 app[web.1]:
2012-01-03T10:33:49+00:00 app[web.1]: Completed in 15ms
2012-01-03T10:33:49+00:00 app[web.1]:
2012-01-03T10:33:49+00:00 app[web.1]: app/controllers/pages_controller.rb:7:in `home'
2012-01-03T10:33:49+00:00 app[web.1]: ActiveRecord::StatementInvalid (PGError: ERROR: syntax error at or near "["
2012-01-03T10:33:49+00:00 app[web.1]: : SELECT "posts".* FROM "posts" WHERE (user_id IN ([]) OR user_id = 2) ORDER BY posts.created_at DESC LIMIT 30 OFFSET 0):
2012-01-03T10:33:49+00:00 app[web.1]:
2012-01-03T10:33:49+00:00 app[web.1]: LINE 1: ...sts".* FROM "posts" WHERE (user_id IN ([]) OR use...
2012-01-03T10:33:49+00:00 app[web.1]:
Pages Controller
class PagesController < ApplicationController
def home
@title = "Home"
if signed_in?
@post = Post.new
@feed_items = current_user.feed.paginate(:page => params[:page])
end
end
User Model
class User < ActiveRecord::Base
has_many :posts, :dependent => :destroy
has_many :relationships, :foreign_key => "follower_id",
:dependent => :destroy
has_many :reverse_relationships, :foreign_key => "followed_id",
:class_name => "Relationship",
:dependent => :destroy
has_many :following, :through => :relationships, :source => :followed
has_many :followers, :through => :reverse_relationships, :source => :follower
attr_accessor :password
attr_accessible :name, :email, :password, :password_confirmation
email_regex = /\A[\w+\-.]+@[a-z\d\-.]+\.[a-z]+\z/i
validates :name, :presence => true,
:length => { :maximum => 50 }
validates :email, :presence => true,
:format => { :with => email_regex },
:uniqueness => { :case_sensitive => false}
validates :password, :presence => true,
:confirmation => true,
:length => { :within => 6..40 }
before_save :encrypt_password
def has_password?(submitted_password)
encrypted_password == encrypt(submitted_password)
end
def self.authenticate(email, submitted_password)
user = find_by_email(email)
return nil if user.nil?
return user if user.has_password?(submitted_password)
end
def self.authenticate_with_salt(id, cookie_salt)
user = find_by_id(id)
(user && user.salt == cookie_salt) ? user : nil
end
def following?(followed)
relationships.find_by_followed_id(followed)
end
def follow!(followed)
relationships.create!(:followed_id => followed.id)
end
def unfollow!(followed)
relationships.find_by_followed_id(followed).destroy
end
def feed
Post.from_users_followed_by(self)
end
private
def encrypt_password
self.salt = make_salt unless has_password?(password)
self.encrypted_password = encrypt(password)
end
def encrypt(string)
secure_hash("#{salt}--#{string}")
end
def make_salt
secure_hash("#{Time.now.utc}--#{password}")
end
def secure_hash(string)
Digest::SHA2.hexdigest(string)
end
end
Post Model
class Post < ActiveRecord::Base
attr_accessible :content
belongs_to :user
validates :content, :presence => true, :length => { :maximum => 140 }
validates :user_id, :presence => true
default_scope :order => 'posts.created_at DESC'
scope :from_users_followed_by, lambda { |user| followed_by(user) }
def self.from_users_followed_by(user)
following_ids = user.following_ids
where("user_id IN (#{following_ids}) OR user_id = ?", user)
end
private
def self.followed_by(user)
following_ids = %(SELECT followed_id FROM relationships
WHERE follower_id = :user_id)
where("user_id IN (#{following_ids}) OR user_id = :user_id",
{ :user_id => user })
end
end
Your problem is here:
Your
following_idswill be an array and when you"#{array}", you get things like[]and[11, 23, 42]. So thatwherewill end up looking like this:neither of those contain valid SQL. Some databases might ignore the stray brackets but PostgreSQL will not.
You need to make two changes:
user_id IN (...)at all iffollowing_idsis empty. Doingc in ()isn’t valid SQL so you don’t want to do that. Again, some databases are lenient and forgiving, PostgreSQL is (thankfully) neither of those things.IN; for that matter, don’t use string interpolation for your SQL at all (unless there is absolutely no other way and that’s rare): we’re not writing PHP in 1999, we’re supposed to know better now. Lucky for you (and the rest of us), AR will do the Right Thing if you hand it an array for a placeholder value.Something like this should work better:
You could also do it like this:
or, my favorite, like this: