mbleigh / acts-as-taggable-on

A tagging plugin for Rails applications that allows for custom tagging along dynamic contexts.
http://mbleigh.lighthouseapp.com/projects/10116-acts-as-taggable-on
MIT License
4.97k stars 1.2k forks source link

Add tenant: option to tagged_with #1102

Open flickgradley opened 1 year ago

flickgradley commented 1 year ago

To improve multi tenancy support, I thought it would be good to add a tenant: option to the tagged_with query. We have 1.2M tagged objects in our database, and adding this tenant filter to that query should make it significantly faster to find objects tagged within a certain tenant.

courtsimas commented 1 year ago

@mbleigh can we get this added in? Would be a huge help for people.

tvongaza commented 12 months ago

This is a great change. We are heavy users of the amazing ActsAsTenant gem and created the following rails initializer to scope our tags & taggings to the set tenant. This PRs change is a lot more flexible, though will require being a bit more explicit on the tenant setting (vs using ActsAsTenant & the require_tenant = true flag).

module ActsAsTaggableOnWithActsAsTenant
  def self.included(base)
    base.class_eval do
      acts_as_tenant(:account)
    end
  end
end

ActsAsTaggableOn::Tag.include(ActsAsTaggableOnWithActsAsTenant)
ActsAsTaggableOn::Tagging.include(ActsAsTaggableOnWithActsAsTenant)

module ActsAsTaggableOnTagNameValidationWithActsAsTenant
  def self.included(base)
    base.class_eval do
      # https://github.com/mbleigh/acts-as-taggable-on/blob/master/lib/acts_as_taggable_on/tag.rb#L17
      def validates_name_uniqueness?
        false
      end
      validates_uniqueness_to_tenant :name
    end
  end
end

ActsAsTaggableOn::Tag.include(ActsAsTaggableOnTagNameValidationWithActsAsTenant)

Related spec (likely needs tweaks for others to use):

require "rails_helper"

RSpec.describe ActsAsTaggableOn::Tag, type: :model do
  it("acts as tenant with account") { expect(subject.account).to eq(ActsAsTenant.current_tenant) }
  context "with different tenant set" do
    let!(:second_account) { AccountCreatorService.call(name: "Example Org") }

    describe "validates_uniqueness_to_tenant" do
      let!(:tag) { ActsAsTenant.with_tenant(second_account) { ActsAsTaggableOn::Tag.create(name: "test") } }

      it "is valid" do
        ActsAsTenant.with_tenant(ActsAsTenant.current_tenant) do
          expect(ActsAsTaggableOn::Tag.create(name: "test")).to be_valid
        end
      end

      it "is invalid" do
        ActsAsTenant.with_tenant(second_account) do
          expect(ActsAsTaggableOn::Tag.create(name: "test")).to be_invalid
        end
      end
    end
  end
end
ragingdave commented 11 months ago

@mbleigh any progress on getting this into a new release? It would be hugely helpful

mbleigh commented 11 months ago

Hey folks, apologies I haven't been the maintainer of this gem for close to a decade so it wouldn't be appropriate for me to decide if it's a good fit.

@seuros I believe you were the last contributor to put a release together, are you still actively working on related things?

seuros commented 11 months ago

I will try to get some time soon to update this gem.

I avoided adding new features unless they are opt-in.