问题
I have a Rails 4 application that is showing some odd behavior on the live production site. Often when creating a Post, the default Rails timestamps (created_at and updated_at) are being set to nil, and the only way to solve it is to restart the Heroku dynos.
After I restart Heroku, I can create Posts again. The Post is being created, but its timestamps are simply set to nil. So when I click 'create post', the server throws a 500 error because I have some code in my post view comparing timestamps.
This never happens on my local development environment, only happens on live Heroku server.
Has anyone experienced this? Can it really be an error in the code if it works fine on local and a 'heroku restart' fixes it (temporarily)? My app is dangerously close to memory maxing out, can that have something to do with it?
Here's my Post create definition:
def create
@post = Post.new(post_params)
@post.user_id = current_user.id
@post.user.increment!(:level, 20)
if @post.save
Subscription.create(:user_id => current_user.id, :post_id => @post.id, :comments_count => 0, :updated_at => (Time.now - 1.minute))
User.where(:auto_sub => true).each do |user|
unless user.id == current_user.id
Subscription.create(:post_id => @post.id, :user_id => user.id, :comments_count => 0, :updated_at => (Time.now - 1.minute))
end
end
redirect_to @post, notice: "Look at you, you're so good at this internet thing"
else
render 'new'
end
end
And here's my show definition:
def show
@post = Post.friendly.find(params[:id])
@user = @post.user
@other_posts = Post.where(:blog => true).sample(4)
if user_signed_in?
@subscription = @post.subscriptions.where(:user_id => current_user.id)
if @subscription.count > 0
if @post.comments_count > 0
@subscription.last.update_attributes(:updated_at => Time.now, :comments_count => @post.comments_count, :last_comment_id => @post.comments.last.id)
else
@subscription.last.update_attributes(:updated_at => Time.now, :comments_count => @post.comments_count)
end
end
end
@comments = @post.comments.paginate(:page => params[:page], :per_page => 20)
redirect_to live_path if Post.friendly.find(params[:id]).live == true
end
Any ideas what it could be?
回答1:
Setting Post.record_timestamps = false would stop updated_at and created_at being set on all subsequent requests to that dyno (if you have more than one dyno, then requests to other dynos would not be affected until they changed that setting too).
A heroku restart fixes things because in a freshly started app that setting has not been changed - you say you only do this from you upvote and update actions. In development, either those actions rarely run, additionally your development environment reloads automatically in response to code changes.
You don't say why you set record_timestamps to false but you should set it back to true once you've done whatever it is that requires that setting. Personally I would write a method like this :
class Post < ActiveRecord::Base
def self.without_timestamps
begin
old_value = record_timestamps
self.record_timestamps = false
yield
ensure
self.record_timestamps = old_value
end
end
end
And use this to wrap blocks that should run without timestamps.
来源:https://stackoverflow.com/questions/31463317/rails-creating-records-with-timestamps-set-to-nil-heroku-restart-solves-it