Act_as_tenant Gem создает ошибки, используя RSpec/FactoryGirl

Я пытаюсь использовать acts_as_tenant гем для охвата запросов SQL для нескольких организаций. Тем не менее, RSpec/FactoryGirl исправляют некоторые хитрости.

Немного предыстории: в моем приложении User а также Grant оба принадлежат к Organization, Только администраторы могут создавать / удалять Grants.

Как советует документация драгоценного камня, я вставил acts_as_tenant :organization в мой Grant а также User моделей. У меня также set_current_tenant_through_filter и определил before_action :set_organization в моем application_controller.rb, Запросы для User а также Grant относятся к текущему пользователю Organization только:

  def set_organization
    if current_user
      current_organization = Organization.find(current_user.organization_id)
      set_current_tenant(current_organization)      
    end
  end

Кажется, все хорошо. Теперь, чтобы написать тесты контроллера:

# grants_controller_spec.rb

describe GrantsController do
  let(:organization) { create(:organization) }
  let(:admin) { create(:user, admin: true, organization_id: organization.id) }
  ...
  before(:each) { log_in admin }
  ...
end

Административная часть вызывает странную ошибку:

 Failure/Error: let(:admin) { create(:user, admin: true, organization_id: organization.id) }
     ActiveRecord::RecordInvalid:
       Validation failed: Organization can't be blank

Так что, хотя я специально передал внешний ключ организации в FactoryGirl, у него все еще есть проблемы с идентификацией Organization,

Когда я закомментирую acts_as_tenantкод, ошибки исчезают. Как я могу сделать тесты зелеными навсегда?

1 ответ

Решение

Это на самом деле имеет мало общего с кодом, который я разместил выше. Виновником была эта строчка, по моему User модель:

attr_accessor :organization_id

Я считаю, что линия помешала фактическому organization_id столбец базы данных от сохранения с моделью. мой UsersController Код может уточнить это:

def create
    @user = User.new(user_params)
    organization = Organization.find_by(name: params[:user][:organization_name])
    if organization.authenticated?(params[:user][:organization_password])
      @user.organization_id = organization.id
      @user.save
      ...
end

Так organization_id был действительно настроен на organization.id, но attr_accessor был оценен первым, поэтому organization_id стал бесполезным виртуальным атрибутом. И столбец БД organization_id был сохранен как nilничего не было передано ему. Это в свою очередь вызвало acts_as_tenant жаловаться, так как я установил current_tenant как организация текущего пользователя, и текущий пользователь не был настроен с внешним ключом.

Мой совет себе и всем остальным, кто сталкивается с этим: проверьте, не скрыты ли имена ваших столбцов БД вашими виртуальными атрибутами.

Другие вопросы по тегам