0

acts_as_tenantgem を使用して、SQL クエリの範囲を複数の組織に限定しようとしています。ただし、RSpec/FactoryGirl はいくつかの汚いトリックを実行しています。

ちょっとした背景: 私のアプリではUserGrantどちらもOrganization. を作成/削除できるGrantのは、管理者ユーザーのみです。

宝石のドキュメントのアドバイスのように、私はモデルとモデルに挿入acts_as_tenant :organizationしました。また、 で a を定義しました。とのクエリは、現在のユーザーのみにスコープが設定されています。GrantUserset_current_tenant_through_filterbefore_action :set_organizationapplication_controller.rbUserGrantOrganization

  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と、エラーはなくなります。テストを完全に緑色にするにはどうすればよいですか?

4

1 に答える 1

0

これは実際には、上に投稿したコードとはほとんど関係がありません。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

Soorganization_idは確かに に設定されてorganization.idいましたattr_accessorが、最初に評価されたためorganization_id、役に立たない仮想属性になりました。そして、db 列organization_idは として保存されましnilた。つまり、何も渡されませんでした。を現在のユーザーの組織として設定し、現在のユーザーが外部キーで設定されていなかったため、これが今度はacts_as_tenant不平を言いました。current_tenant

私自身とこれに出くわした他のすべての人への私のアドバイス: db 列名が仮想属性によって隠されているかどうかを確認してください。

于 2015-07-17T23:51:47.267 に答える