2012-01-03 72 views
1

当我尝试将我的应用程序部署到Heroku(它在我的本地主机上正常工作时)时出现500错误。不知道为什么会这样。当我将应用程序部署到Heroku时发生500错误

我该如何解决?错误的详细信息都低于...

错误详细信息

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]:    

页面控制器

class PagesController < ApplicationController 

def home 
    @title = "Home" 
    if signed_in? 
     @post = Post.new 
     @feed_items = current_user.feed.paginate(:page => params[:page]) 
    end 
end 

用户模型

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+\-.][email protected][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 

邮政型号

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 
+0

这是无效的,范围为用户模型提供了什么? WHERE(user_id IN([])或user_id = 2) – easyjo 2012-01-03 10:47:34

+0

@easyjo我该如何检查? (对不起,我是一个新手到rails ..)我通过上面的编辑添加了用户模型的一部分,也许这有助于... – hikmatyar 2012-01-03 10:51:20

+0

你是不是使用has_many关系为用户的帖子? – easyjo 2012-01-03 10:53:21

回答

1

你的问题是在这里:

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不会。

你需要做出两个改变:

  1. 不包括user_id IN (...)在所有如果following_ids是空的。做c in()是无效的SQL,所以你不想这样做。同样,有些数据库是宽松和宽容的,PostgreSQL是(幸好)没有这些东西。
  2. 请勿使用简单的字符串插值为您的IN提供值;对于这个问题,根本不要为你的SQL使用字符串插值(除非绝对没有其他方法,这很少见):我们不是在1999年编写PHP,现在应该知道更好。对你(以及我们其他人)来说幸运的是,如果你为一个占位符值递交一个数组,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 
+0

谢谢,这非常有帮助!我做了修复,现在应用程序运行得很好。 – hikmatyar 2012-01-05 12:41:15

3

这是一个代码问题,而不是Heroku的问题。

问题在于用户模型中的Post.from_users_followed_by(self)。无论这包含的是不是Postgres友好的,或者不受零值保护。

+0

谢谢尼尔,但我该如何解决?此外,它在开发模式下工作正常,所以不会表明这不是一个代码问题。 – hikmatyar 2012-01-03 10:53:25

+0

哦嗨尼尔,有一个upvote – easyjo 2012-01-03 10:55:20

+0

对我来说,这表明你在开发中使用不同的数据库(或版本)或者可能配置不同,或者只是具有不同的数据(这不会导致数组为空)。这个问题可能在'from_users_followed_by_self'范围内 – 2012-01-03 11:14:18

相关问题