Mark
Mark

Reputation: 6455

RSpec - refreshing associations

I have a LabCollection:

class LabCollection < ApplicationRecord
  # Relationships
  belongs_to :lab_container, polymorphic: true, optional: true
  has_many :lab_collection_labs
  has_many :labs, -> { published }, through: :lab_collection_labs
  has_many :lab_collection_inclusions, dependent: :destroy
end

It has many LabCollectionLabs:

class LabCollectionLab < ApplicationRecord
  acts_as_list scope: :lab_collection_id, add_new_at: :bottom
  belongs_to :lab_collection
  belongs_to :lab
end

Which has a lab ID and belongs to a lab.

I have a spec which tests how new associations are created, and it's failling at the following point:

context 'when the lab container has labs already present' do
        it 'removes the present labs and adds the new ones' do
          subject = RawLabAdder
          expect(populated_lab_collection.labs).to eq labs
          subject.new(populated_lab_collection, [lab4.id, lab5.id]).perform
          expect(populated_lab_collection.labs).not_to eq labs
          binding.pry
          expect(populated_lab_collection.labs).to eq [lab4, lab5]
        end
      end

If you need to see the internal working of the code let me know, however the issue seems to be with RSpec and refreshing associations. When I hit the binding.pry point and call populated_lab_collection.lab_collection_labs

populated_lab_collection.lab_collection_labs
=>
[lab_collection_lab_4, lab_collection_lab_5]

However when I call .labs instead:

populated_lab_collection.labs
=>
[]

Inspecting the lab_collection_labs, I can see that they each have a lab_id and that a lab exists for those ID's. I believe my problem is that I'm not refreshing the records correctly, however I've tried:

      # populated_lab_collection.reload
      # populated_lab_collection.lab_collection_labs.reload
      # populated_lab_collection.lab_collection_labs.each do |x|
      #   x.lab.reload
      # end
      # populated_lab_collection.labs.reload

Any advice on how I can get RSpec to correctly read in a records nested associations is greatly appreciated. As I say when I inspect the record, it has 2 lab_inclusion_labs, which each have a lab, however the parent record apparently has no labs.

EDIT: RawLabAdder class:

module LabCollections
  class RawLabAdder

    def initialize(incoming_lab_collection, lab_ids = [])
      @lab_ids = lab_ids
      @lab_collection = incoming_lab_collection
    end

    def perform
      remove_associated_labs
      add_labs
    end

    private

    def add_labs
      @lab_ids.each do |x|
        lab = Lab.find(x)
        LabCollectionInclusionAdder.new(@lab_collection, lab).perform
      end
    end

    def remove_associated_labs
      @lab_collection.lab_collection_inclusions.map(&:destroy)
      @lab_collection.lab_collection_labs.map(&:destroy)
    end
  end
end

Upvotes: 0

Views: 1215

Answers (1)

A_rayB
A_rayB

Reputation: 121

If you create an instance in a before hook or in a spec and then perform some database related work on it the instance you have will no longer reference the up to date information.

Try reloading the populated_lab_collection before asserting.

expect(populated_lab_collection.reload.labs).not_to eq labs

Upvotes: 3

Related Questions