Search code examples
ruby-on-railsruby-on-rails-3activerecordrspecrspec-rails

weird RSpec behavior when runnig controller spec and retrieving last record


this is log from debugger when I run my PostsController spec on create action. I'm not changing or manipulating any db records during runtime with console so this is no special case.

(rdb:1) p Post.last
#<Post id: 2, author_id: 3, title: "My ultra cool post", content: "Lorem ipsum", deleted_at: nil, created_at: "2012-08-31 09:21:20", updated_at: "2012-08-31 09:21:20", published_at: nil, display_from: nil>

(rdb:1) p Post.all
[#<Post id: 2, author_id: 3, title: "My ultra cool post", content: "Lorem ipsum", deleted_at: nil, created_at: "2012-08-31 09:21:20", updated_at: "2012-08-31 09:21:20", published_at: nil, display_from: nil>, 
 #<Post id: 3, author_id: 2, title: "My ultra cool post", content: "Lorem ipsum", deleted_at: nil, created_at: "2012-08-31 09:21:20", updated_at: "2012-08-31 09:21:20", published_at: nil, display_from: nil>]

(rdb:1) p Post.last
#<Post id: 2, author_id: 3, title: "My ultra cool post", content: "Lorem ipsum", deleted_at: nil, created_at: "2012-08-31 09:21:20", updated_at: "2012-08-31 09:21:20", published_at: nil, display_from: nil>

So Post.all shows that post 3 exist but Post.last not

but when I do

(rdb:1) p Post.all.last
#<Post id: 3, author_id: 2, title: "My ultra cool post", content: "Lorem ipsum", deleted_at: nil, created_at: "2012-08-31 09:21:20", updated_at: "2012-08-31 09:21:20", published_at: nil, display_from: nil>

Controller file:

class PostsController < ApplicationController
  def create
    @post.author = current_user
    @post.save
    debugger # this is where I'm debugging
    respond_with @post
  end
end
  • this behavior works in develompent code correctly

the only implication for me is that in my spec I'll do

 response.should redirect_to Post.all.last

insted of

 response.should redirect_to Post.last

I know that in Ralis there are some cases where Active Record triggers call before DB is ready ? but in this case the ActiveRecord actually know about existance of this record with .all call but not with .last, so this is just weird

Any thoughts on this?


Solution

  • This behavior is quite logic: default order is based on created_at, and your objects both have the same created_at date time.

    So the database has to make a (random) choice.


    Actually, I just read dthe default order depends on the database you're working with. To be sure you get what you expect use a default_scope, for instance:

    default_scope order('id ASC')