View Source TagsMultiTenant

TagsMultiTenant allows you to manage tags associated to your records.

It also allows you to specify various contexts

installation

Installation

  1. Add tags_multi_tenant to your list of dependencies in mix.exs:
  def deps do
    [{:tags_multi_tenant, "~> 0.1.16"}]
  end
  1. Configure TagsMultiTenant to use your repo in config/config.exs:
  # Options
  # taggable_id - This field is default :integer, but you can set it as :uuid

  config :tags_multi_tenant,
    repo: ApplicationName.Repo,
    taggable_id: :integer
  1. Install your dependencies:
  mix deps.get
  1. Generate the migrations:
  mix TagsMultiTenant.install

This will create two migration files, xxxxx_create_tag.exs and xxxxx_create_tagging.exs. You can leave these in the repo/migrations directory if you are:

* not using a multi-tenant database
* using a multi-tenant database, but prefer to leave the tagging in the 'public' schema

If you prefer to use the multi-tenant features, you will need to move the two migration files to the tenant_migrations directory prior to applying the migrations.

  1. Run the migrations:
  mix ecto.migrate

If you are using the Triplex package to manage multi-tenant migrations, you can use

  mix triplex.migrate

to migrate these migrations.

include-it-in-your-models

Include it in your models

Now, you can use the library in your models.

You should add the next line to your taggable model:

use TagsMultiTenant.TagAs, :tag_context_name

i.e.:

  defmodule Post do
    use Ecto.Schema
    use TagsMultiTenant.TagAs, :categories

    import Ecto.Changeset

    schema "posts" do
      field :title, :string
      field :body, :boolean

      timestamps()
    end

    def changeset(struct, params \\ %{}) do
      struct
      |> cast(params, [:title, :body])
      |> validate_required([:title])
    end
  end

As you can see, we have included the context categories

Now we can use a set of metaprogrammed functions:

If you are using the plugin as a single tenant setup, the following functions will work.

Post.add_category(struct, tag) - Passing a persisted struct will allow you to associate a new tag

Post.add_categories(struct, tags) - Passing a persisted struct will allow you to associate a new list of tags

Post.add_category(tag) - Add a Tag without associate it to a persisted struct, this allow you have tags availables in the context. Example using Post.categories

Post.remove_category(struct, tag) - Will allow you to remove the relation struct - tag, but the tag will persist.

Post.remove_category(tag) - Will allow you to remove a tag in the context Post - category. Tag and relations with Post will be deleted.

Post.rename_category(old_tag, new_tag) - Will allow you to rename the tag name.

Post.categories_list(struct) - List all associated tags with the given struct

Post.categories - List all associated tags with the module

Post.categories_queryable - Same as Post.categories but it returns a queryable instead of a list.

Post.tagged_with_category(tag) - Search for all resources tagged with the given tag

Post.tagged_with_categories(tags) - Search for all resources tagged with the given list tag

Post.tagged_with_query_category(queryable, tags) - Allow to concatenate ecto queries and return the query.

Post.tagged_with_query_categories(queryable, tags) - Same than previous function but allow to receive a list of tags

If you are using the plugin in a multi-tenant environment, then each function accepts 'opts' in order to pass the 'prefix' value to the database. Here is an example of passing tenant value as prefix.

Post.add_category(struct, tag, prefix: 'client_test') - Passing a persisted struct will allow you to associate a new tag

working-with-functions

Working with functions

If you want you can use directly:

TagsMultiTenant.add/4

TagsMultiTenant.remove/4

TagsMultiTenant.rename/5

TagsMultiTenant.tag_list/3

TagsMultiTenant.tag_list_queryable/2

TagsMultiTenant.tagged_with/4

TagsMultiTenant.tagged_with_query/3