2

I have this code in spec/models:

  describe "update ranking position and player's points" do
    before do
      @player.save
      @player2 = Player.create(firstname: "Second", lastname: "Player", nickname: "second99")
      @match = Match.create(
              { loserscore: 1, winner_player_id: @player.id,
                loser_player_id: @player2.id })
      @player.update_rank
      @player2.update_rank
      Player.update_position
    end

    it { expect(@player.position).to eq 1 }
  end

This is the method from model:

  def self.update_position
    @players = Player.all
    @players = @players.sort_by { |player| player.rank.to_i }.reverse

    @players.each_with_index do |player, index|
      player.position = index + 1
      player.save
       end
  end

When I call this method in controller everything is OK (ranking is updated).

But in RSpec I get nil

  1) Player update ranking position and player's points should eq 1
     Failure/Error: it { expect(@player.position).to eq 1 }

       expected: 1
            got: nil

I tried debug it so I wrote in RSpec:

p Player.all.count

but it shows

2

So for me everything looks OK - there are two rows in Player table. Every others tests passed. I have the problem only with this one method (this is only one class method in this model). App works fine.

Why called method doesn't change position column in Player table?

3
  • 1
    Have you tried throwing an @player.reload after Player.update_position? Commented Jul 27, 2015 at 16:34
  • It works. Thank you. I am a little surprised. Why doesn't it work without @player.reload? Commented Jul 27, 2015 at 16:37
  • 1
    No problem! Rails doesn't know it needs to reload the instance's data (it already loaded the @player model) after you run the class method update_positions so we need to reload the instance so it gets the fresh data from the table. It's one of those "annoying" testing quirks for me (there might be a better answer to this though!) Commented Jul 27, 2015 at 16:41

1 Answer 1

3

You need to reload the instance variables after performing any updates.

it 'should set @player as winner' do
  @player.reload
  expect(@player.position).to eq(1)
end
Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.