RubyTutorial.org: Invalid SQL statement generates 500 response on pages#home
While the view contains(what I believe) is the correct UNLESS statement to display a feed, the SQL method from micropost.rb model seems to be invalid when a user is not following anyone. This error is transparent in a deployment environment(such as Heroku) -- here is the log snippet which generates a 500 response from the application:
Started GET "/" for 71.180.163.2 at Mon Jan 31 12:10:07 -0800开发者_StackOverflow 2011
Processing by PagesController#home as HTML
Completed in 9ms
ActiveRecord::StatementInvalid (PGError: ERROR: syntax error at or near ")"
LINE 1: ...* FROM "microposts" WHERE (user_id IN () OR user_...
^
: SELECT "microposts".* FROM "microposts" WHERE (user_id IN () OR user_id = 1) ORDER BY microposts.created_at DESC LIMIT 30 OFFSET 0):
app/controllers/pages_controller.rb:6:in `home'
The question is, how do I solve this issue without a hack-fix such as automatically following a user on User.create!
It it helps at all, the gist for this issue is here: https://gist.github.com/804754
Removing the initial self.from_users_followed_by method in the micropost model, leaving the private self.followed_by(user) method to stand alone, seems to have resolved the issue. All tests passing.
From 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'
#Return microposts from the users being followed by the given user--
scope :from_users_followed_by, lambda { |user| followed_by(user) }
#
# def self.from_users_followed_by(user)
# followed_ids = user.following.map(&:id).join(", ")
# where("user_id IN (#{followed_ids}) OR user_id = ?", user)
# end
private
#Return an SQL condition for users followed by the given user.
#We include the user's own ID as well--
def self.followed_by(user)
followed_ids = %(SELECT followed_id FROM relationships
WHERE follower_id = :user_id)
where("user_id IN (#{followed_ids}) OR user_id = :user_id",
:user_id => user)
end
end
It is never necessary to build a query string by hand like you are doing in your from_users_followed_by
method. I would do something like:
def self.from_users_followed_by(user)
followed_ids = user.following.map(&:id) + user.id
where(:user_id => followed_ids)
end
精彩评论