繁体   English   中英

将应用程序部署到Heroku时出现500错误

[英]500 error when I deploy my app to Heroku

当我尝试将我的应用程序部署到Heroku时,我收到500错误(它在我的localhost上工作正常)。 不知道为什么会这样。

我该如何解决? 错误详情如下......

错误详情

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

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

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

你的问题在这里:

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. 如果following_ids为空,则不要包含user_id IN (...) c in ()执行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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM