2012-01-03 96 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

相關問題