1

I don't understand why something in development works, but in production it has different behaviors, here's my other example. In this example, the comments are always ordered by DESC in development, but in production if a user likes a comment then that comment moves to the bottom of the list as if the comment was recreated.

Why would this be?

comments_controller

class CommentsController < ApplicationController
  before_action :set_commentable, only: [:index, :new, :create]
  before_action :set_comment, only: [:edit, :update, :destroy]
  before_action :correct_user, only: [:edit, :update, :destroy]

  def index
    @comments = @commentable.comments.order("created_at DESC")
  end

  def new
    @comment = @commentable.comments.new
  end

  def create
    @comment = @commentable.comments.new(comment_params)
    if @comment.save
      redirect_to @commentable, notice: "Comment created."
    else
      render :new
    end
  end

  def edit
  end

  def update
    if @comment.update_attributes(comment_params)
      redirect_to :back, notice: "Comment was updated."
    else
      render :edit
    end
  end

  def destroy
    @comment.destroy
    redirect_to @comment.commentable, notice: "Comment destroyed."
  end

  def like
    @comment = Comment.find(params[:id])
    @comment_like = current_user.comment_likes.build(comment: @comment)
    if @comment_like.save
      @comment.increment!(:likes)
      flash[:success] = 'Thanks for liking!'
    else
      flash[:error] = 'Too many likes'
    end  
    redirect_to(:back)
  end

  private

  def set_commentable
    @commentable = find_commentable
  end

  def set_comment
    @comment = current_user.comments.find(params[:id])
  end

  def correct_user
    @comment = current_user.comments.find_by(id: params[:id])
    redirect_to root_url, notice: "Not authorized to edit this comment" if @comment.nil?
  end

  def find_commentable
    if params[:goal_id]
      Goal.find(params[:goal_id])
    elsif params[:habit_id]
      Habit.find(params[:habit_id])
    elsif params[:valuation_id]
      Valuation.find(params[:valuation_id])
    elsif params[:stat_id]
      Stat.find(params[:stat_id])
    end
  end

  def comment_params
    params[:comment][:user_id] = current_user.id
    params.require(:comment).permit(:content, :commentable, :user_id, :like)
  end
end

comment_like.rb

class CommentLike < ActiveRecord::Base
  belongs_to :user
  belongs_to :comment
  belongs_to :habit
  belongs_to :stat
  belongs_to :valuation
  belongs_to :goal
  validates :user, uniqueness: { scope: :comment }
  belongs_to :liker, class_name: 'User', foreign_key: :user_id
  belongs_to :liked_comment, class_name: 'Comment', foreign_key: :comment_id
end

comment.rb

class Comment < ActiveRecord::Base
    after_save :create_notification
  has_many :notifications
  has_many :comment_likes   
  has_many :likers, through: :comment_likes, class_name: 'User', source: :liker
  belongs_to :habit
  belongs_to :stat
  belongs_to :valuation
  belongs_to :goal
    belongs_to :user
  validates :user, presence: true

private

  def create_notification
    author = 
      if goal
        goal.user
      #elsif comment_like
      # comment_like.user
      elsif habit
       habit.user
      elsif stat
        stat.user
      elsif valuation
        valuation.user
      end
    notifications.create(
      comment:      self,
      likes:        likes,
      habit:        habit,
      stat:         stat,
      goal:         goal,
      valuation:    valuation,
      user:         author,      
      read:         false
    )
  end
end

schema

  create_table "comment_likes", force: true do |t|
    t.integer  "user_id"
    t.integer  "comment_id"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
  end

  create_table "comments", force: true do |t|
    t.text     "content"
    t.integer  "goal_id"
    t.integer  "habit_id"
    t.integer  "valuation_id"
    t.integer  "stat_id"
    t.integer  "commentable_id"
    t.string   "commentable_type"
    t.integer  "user_id"
    t.datetime "created_at",       null: false
    t.datetime "updated_at",       null: false
    t.integer  "likes"
  end

  add_index "comments", ["commentable_id", "commentable_type"], name: "index_comments_on_commentable_id_and_commentable_type"
  add_index "comments", ["commentable_type", "commentable_id"], name: "index_comments_on_commentable_type_and_commentable_id"
  add_index "comments", ["user_id"], name: "index_comments_on_user_id"
Community
  • 1
  • 1
AnthonyGalli.com
  • 2,796
  • 5
  • 31
  • 80
  • Are you using the same database system? You're not using sqlite in development and postgres in production, right? – simonwo Jun 24 '15 at 12:00
  • Yea I'm using sqlite in development and postgres in production. How is that part of the problem though? @simonwo – AnthonyGalli.com Jun 24 '15 at 15:04
  • Because although the accepted answer has fixed your problem, the _actual_ issue is that your two database systems work in slightly different ways: here they have different default ordering. You wouldn't have had a problem at all if you'd use the same DBMS. See http://stackoverflow.com/a/29743695/3729369. – simonwo Jun 24 '15 at 15:52

1 Answers1

4

For Rails 4.0+ you need to add a scope to your Comment model, so it looks like this:

class Comment < ActiveRecord::Base
  default_scope { order('created_at DESC') }
  ...

end

For more you can read docs.

Walerian Sobczak
  • 817
  • 2
  • 10
  • 23