Module: ConcernsOnRails::Models::Taggable
- Extended by:
- ActiveSupport::Concern
- Defined in:
- lib/concerns_on_rails/models/taggable.rb
Overview
Lightweight, dependency-free tagging over a single string column. Tags are stored delimiter-joined in one column — no join tables, no tagging engine — so it works on any database, including SQLite.
class Article < ApplicationRecord
include ConcernsOnRails::Taggable
taggable_by :tags # default column :tags
# taggable_by :skills, downcase: true # custom column, case-folded
end
a = Article.new
a.tag_list = "Ruby, Rails, Ruby" # accepts a String or an Array
a.tag_list # => ["Ruby", "Rails"] (stripped + de-duped)
a.("api"); a.("Rails")
a.tagged_with?("ruby") # membership predicate
a.save!
Article.tagged_with("ruby", "rails") # records carrying BOTH tags
Article.tagged_with("ruby", "go", any: true) # records carrying ANY tag
Article. # sorted unique tags in use
Notes:
* Matching is boundary-safe ("rail" does not match "rails").
* A tag cannot contain the delimiter (default ",") — input containing
it is split into multiple tags on the spot (`add_tags("a,b")` adds
"a" and "b"), everywhere, so what you read back always matches what
a save would have produced.
* Reach for acts-as-taggable-on when you need tag contexts, ownership,
tag counts/clouds, or polymorphic tags shared across models.
Defined Under Namespace
Modules: ClassMethods
Constant Summary collapse
- LABEL =
"ConcernsOnRails::Models::Taggable".freeze
- DEFAULT_FIELD =
:tags- DEFAULT_DELIMITER =
",".freeze
Instance Method Summary collapse
- #add_tags(*names) ⇒ Object (also: #add_tag)
- #remove_tags(*names) ⇒ Object (also: #remove_tag)
-
#tag_list ⇒ Object
---- instance methods ----.
- #tag_list=(value) ⇒ Object
-
#tagged_with?(tag) ⇒ Boolean
(also: #has_tag?)
AND semantics for delimiter-containing input, mirroring the class-level tagged_with default: tagged_with?("a,b") is true when BOTH tags are set.
Instance Method Details
#add_tags(*names) ⇒ Object Also known as: add_tag
145 146 147 148 |
# File 'lib/concerns_on_rails/models/taggable.rb', line 145 def (*names) self.tag_list = tag_list + names.flatten tag_list end |
#remove_tags(*names) ⇒ Object Also known as: remove_tag
151 152 153 154 155 |
# File 'lib/concerns_on_rails/models/taggable.rb', line 151 def (*names) drop = taggable_coerce(names.flatten) self.tag_list = tag_list.reject { |t| drop.include?(t) } tag_list end |
#tag_list ⇒ Object
---- instance methods ----
136 137 138 |
# File 'lib/concerns_on_rails/models/taggable.rb', line 136 def tag_list self.class.taggable_split(self[self.class.taggable_field]) end |
#tag_list=(value) ⇒ Object
140 141 142 143 |
# File 'lib/concerns_on_rails/models/taggable.rb', line 140 def tag_list=(value) = taggable_coerce(value) self[self.class.taggable_field] = .empty? ? nil : .join(self.class.taggable_delimiter) end |
#tagged_with?(tag) ⇒ Boolean Also known as: has_tag?
AND semantics for delimiter-containing input, mirroring the class-level tagged_with default: tagged_with?("a,b") is true when BOTH tags are set.
160 161 162 163 |
# File 'lib/concerns_on_rails/models/taggable.rb', line 160 def tagged_with?(tag) parts = self.class.taggable_split(tag.to_s) parts.any? && (parts - tag_list).empty? end |