# TagsMultiTenant
TagsMultiTenant allows you to manage tags associated to your records.
It also allows you to specify various contexts
## Installation
1. Add `tags_multi_tenant` to your list of dependencies in `mix.exs`:
```elixir
def deps do
[{:tags_multi_tenant, "~> 0.1.16"}]
end
```
2. Configure TagsMultiTenant to use your repo in `config/config.exs`:
```elixir
# 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
```
3. Install your dependencies:
```
mix deps.get
```
4. 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.
5. 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
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.:
```elixir
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
If you want you can use directly:
[`TagsMultiTenant.add/4`](https://hexdocs.pm/tags_multi_tenant/TagsMultiTenant.html#add/4)
[`TagsMultiTenant.remove/4`](https://hexdocs.pm/tags_multi_tenant/TagsMultiTenant.html#remove/4)
[`TagsMultiTenant.rename/5`](https://hexdocs.pm/tags_multi_tenant/TagsMultiTenant.html#rename/5)
[`TagsMultiTenant.tag_list/3`](https://hexdocs.pm/tags_multi_tenant/TagsMultiTenant.html#tag_list/3)
[`TagsMultiTenant.tag_list_queryable/2`](https://hexdocs.pm/tags_multi_tenant/TagsMultiTenant.html#tag_list_queryable/2)
[`TagsMultiTenant.tagged_with/4`](https://hexdocs.pm/tags_multi_tenant/TagsMultiTenant.html#tagged_with/4)
[`TagsMultiTenant.tagged_with_query/3`](https://hexdocs.pm/tags_multi_tenant/TagsMultiTenant.html#tagged_with_query/3)