views:

42

answers:

1

I have a one-to many relationship in Rails:

class User < ActiveRecord::Base
  has_many :activities, :order => "added_at DESC"


class Activity < ActiveRecord::Base
  belongs_to :user

I have a method in Activity:

def self.test_message(user, message)
  user.activities << Activity.create do |activity|
    activity.message = message
    activity.added_at = Time.now
  end    
end

and the following unit test:

require 'test_helper'

class ActivityTest < ActiveSupport::TestCase

  def test_test_message
    #From fixture
    alice = User.find_by_name("alice")
    assert_equal 0, alice.activities.count

    Activity.test_message(alice, "Hello")
    assert_equal 1, alice.activities.count

    Activity.test_message(alice, "Goodbye")
    assert_equal 2, alice.activities.count
    assert_equal "Hello", alice.activities.find(:first).message

    #The following line fails with: Goodbye expected but was Hello
    assert_equal "Goodbye", alice.activities.find(:last).message,
    acts = alice.activities
    assert_equal 2, acts.count
    assert_equal "Goodbye", acts[1].message
  end
end

which fails on the indicated line, but I can't work out why.

Also, using activities.find(:last) works when using the development environment, but only fails under the test environment. I have dropped and rebuilt the database.

A: 

This seems to be an issue with using the :order flag in your association declaration. This post isn't the exact situation you're experiencing, but it recommends against the practice in general:

http://weblog.jamisbuck.org/2007/1/18/activerecord-association-scoping-pitfalls

(I'm not sure if these suggestions are still relevant, but I was seeing the same behavior as you in Rails 2.3.3 until I made the changes below.)

I set up your app locally and tried applying the technique from comment #4 by adding

def Activity.by_added_at
  find :all, :order => 'added_at DESC'
end

and changing your find(:first) and find(:last) in the test to .by_added_at.first and .by_added_at.last, which returns more stable results.

One other suggestion -- your test is pretty big right now. You might consider splitting it out into multiple tests, each of which tests one or two conditions at most.

Kyle
Many thanks, that's sorted it. Point noted about test sizes.
Mike Sutton