Search code examples
ruby-on-railsrspecrspec-rails

FactoryBot one record associated with many attributes


I have User, Assignment and Department models. My Assignment model has 2 belongs_to associations with the User model as requestor and assignee.

The User and Assignment model also in turn belongs_to a department.

I want to run a validation on my Assignment such that the assignment, requestor and assignee all belong to the same department.

This is my code for the models

# app/models/assignment.rb
class Assignment < ApplicationRecord
  belongs_to :requestor, class_name: "User", foreign_key: "requested_by"
  belongs_to :assignee, class_name: "User", foreign_key: "assigned_to"

  belongs_to :department
end

# app/models/user.rb
class User < ApplicationRecord
  has_many :user_departments, class_name: "UserDepartment"
  has_many :departments, through: :user_departments

  belongs_to :department
end

# app/models/department.rb
class Department < ApplicationRecord
  has_many :user_departments, class_name: "UserDepartment"
  has_many :users, through: :user_departments

  has_many :assignments
  has_many :users
end

This is the code for my test

# spec/factories/assignment.rb
FactoryBot.define do
  sequence(:title) { |n| "Title #{n}" }
  sequence(:description) { |n| "Description #{n}" }

  factory :assignment do
    title
    description
    image { Rack::Test::UploadedFile.new(Rails.root.join('spec/support/Floyd.jpeg'), 'image/jpeg') }
    release_date { DateTime.now >> 1 }
    department { create(:department) }
    requestor create(:user, :bm, department: "I want to use the same department as created in earlier line here")
    assignee create(:user, :mu, department: "I want to use the same department as created in earlier line here")
  end
end

Where should I define the department so I can use the same department across all three associations.


Solution

  • Have you tried self.department? It worked in my code:

    # spec/factories/assignment.rb
    FactoryBot.define do
      sequence(:title) { |n| "Title #{n}" }
      sequence(:description) { |n| "Description #{n}" }
    
      factory :assignment do
        title
        description
        image { Rack::Test::UploadedFile.new(Rails.root.join('spec/support/Floyd.jpeg'), 'image/jpeg') }
        release_date { DateTime.now >> 1 }
        department { create(:department) }
        requestor { create(:user, :bm, department: self.department) }
        assignee { create(:user, :mu, department: self.department) }
      end
    end