2
votes

I am using acts-as-taggable gem https://github.com/mbleigh/acts-as-taggable-on and jQueryTokenInput plugin to add tags to my image model . Tags are created and added fine so far. I followed the tutorial http://bloginius.com/blog/2013/12/31/how-integrate-acts-as-taggable-on-with-jquery-token-input-with-rails-3/. Now however, I want to be able to give ownership of the tag to the current_user at the time the tag is created. As in the gem' s github page, I have tried

@some_user.owned_taggings
@some_user.owned_tags

with no satisfactory results. I proceeded and added a user_id to the tags table. Is there a tagsController associated with the acts-as-taggable-on gem that I can modify with a before_save to set the user_id for the tag ? Thanks!!

1

1 Answers

0
votes

A section of the acts-as-taggable-on README dedicated to ownership, and is useful to work through with the specifics of your models.

But, I don't think the methods provided are correct -- they will apply all owned tags (owned by anyone, that is), to each owner<>item relationship. Here's how I'd do it:

DEFAULT_ACTSASTAGGABLEON_TYPE = :tag

module TagToOwner
  extend ActiveSupport::Concern

  private
    def add_owned_tag(item, owner, tags_to_add, options = {})
      own_tag(item, owner, arrayify(tags_to_add), "add", options)
    end

    def remove_owned_tag(item, owner, tags_to_add, options = {})
      own_tag(item, owner, arrayify(tags_to_add), "subtract", options)
    end

    def own_tag(item, owner, tags_to_add, direction = "add", opts)
      tag_type = (options[:tag_type] || DEFAULT_ACTSASTAGGABLEON_TYPE)
      owned_tag_list = item.owner_tags_on(owner, tag_type).map(&:name)

      if direction == "subtract"
        owned_tag_list = owned_tag_list.reject{|n| n.in?(tags_to_add)}
      else
        owned_tag_list.push(*tags_to_add)
      end

      owner.tag(item, with: stringify(owned_tag_list), on: tag_type, skip_save: (options[:skip_save] || true))
    end

    def arrayify(tags_to_add)
      return tags_to_add if tags_to_add.is_a?(Array)
      tags_to_add.split(",")
    end

    def stringify(tag_list)
      tag_list.inject('') { |memo, tag| memo += (tag + ',') }.chomp(",")
    end
end

And:

class MyModelController < ApplicationController
  include TagToOwner
  # ...
  def create
    @my_model = MyModel.new(my_model_params)
    add_tags
    # ...
  end
  # ...
  def update
    add_tags
    # ...
  end

  private
    def add_tags
      return unless params[:tag_list] && "#{params[:tag_list]}".split(",").any?
      return unless validate_ownership_logic # <- e.g. `current_user`

      add_owned_tag(@my_model, current_user, params[:tag_list])
    end
end

Note I have filed an issue against acts-as-taggable-on, and a corresponding pull request, to correct their README.