module OrbitTag module Taggable extend ActiveSupport::Concern module ClassMethods def taggable init_tag end private def init_tag class_eval do field :tags_to_destroy, type: Array, default: [] field :tagged_ids, type: Array, default: [] has_many :taggings, as: :taggable, autosave: true, dependent: :destroy accepts_nested_attributes_for :taggings, allow_destroy: true after_save :remove_taggings, unless: Proc.new{self.tags_to_destroy.blank?} def remove_id(id) self.class.without_callback(:save, :after, :remove_taggings) do self.update_attribute(:tagged_ids, self.tagged_ids - [id.to_s]) end end def sorted_tags if tags.blank? [] else tag_array = tags.inject([]){ |result, value| result << [value.name, value] } tag_array.sort.map{|x| x[1] } end end def tags self.taggings.blank? ? [] : self.taggings.map{|t| t.tag}.compact end def tags=(tag_ids) ids = [tag_ids].flatten tag_ids.delete('') self.tagged_ids = tag_ids ids = self.taggings.blank? ? [] : self.taggings.map{|t| t.tag.id} tag_ids.each do |tag_id| unless ids.include? tag_id self.taggings.build(tag_id: tag_id) end end self.tags_to_destroy = self.taggings.where(:tag_id.in => (ids - tag_ids)).map{|t| t.id} end def tag_ids self.taggings.blank? ? [] : self.taggings.map{|t| t.tag.id} end def tag_ids=(ids) self.tags = ids end private def remove_taggings self.taggings.where(:_id.in => self.tags_to_destroy).destroy self.class.without_callback(:save, :after, :remove_taggings) do self.update_attribute(:tags_to_destroy, []) end end end end end end module Tagging extend OrbitCoreLib::AppBackendUtility def get_tags @module_app ? @module_app.tags : Tag.all end end end