Class: Tag
- Inherits:
-
ApplicationRecord
- Object
- ActiveRecord::Base
- ApplicationRecord
- Tag
- Defined in:
- app/models/tag.rb
Overview
== Schema Information
Table name: tags
Database name: primary
id :integer not null, primary key
name :string(255)
public :boolean default(FALSE), not null
slug :string
taggings_count :integer
created_at :datetime not null
updated_at :datetime not null
Indexes
index_tags_on_name (name) UNIQUE
index_tags_on_name_lower_unique (lower((name)::text)) UNIQUE
index_tags_on_public (public)
index_tags_on_slug_unique (slug) UNIQUE
index_tags_on_taggings_count (taggings_count)
Constant Summary collapse
- NAME_FORMAT =
/\A[a-z0-9]+(?:-[a-z0-9]+)*\z/
Constants included from Models::Schedulable
Models::Schedulable::SIMPLE_FORM_OPTIONS
Instance Attribute Summary collapse
- #name ⇒ Object readonly
- #slug ⇒ Object readonly
Has many collapse
- #activity_types ⇒ ActiveRecord::Relation<ActivityType>
-
#articles ⇒ ActiveRecord::Relation<Article>
Polymorphic associations through taggings.
- #digital_assets ⇒ ActiveRecord::Relation<DigitalAsset>
- #floor_plan_displays ⇒ ActiveRecord::Relation<FloorPlanDisplay>
- #items ⇒ ActiveRecord::Relation<Item>
- #product_lines ⇒ ActiveRecord::Relation<ProductLine>
- #showcases ⇒ ActiveRecord::Relation<Showcase>
- #taggings ⇒ ActiveRecord::Relation<Tagging>
Class Method Summary collapse
-
.by_taggable_type ⇒ ActiveRecord::Relation<Tag>
A relation of Tags that are by taggable type.
-
.canonicalize_input(name) ⇒ Object
Convert human-entered separators to the canonical dash form without transliterating Unicode or discarding punctuation.
-
.find_or_create_all_by_name(names) ⇒ Array<Tag>
Find or create multiple tags by name.
-
.find_or_create_by_name(name) ⇒ Tag
Find or create a tag by canonical name (case-insensitive).
-
.most_used ⇒ ActiveRecord::Relation<Tag>
A relation of Tags that are most used.
-
.ordered ⇒ ActiveRecord::Relation<Tag>
A relation of Tags that are ordered.
-
.public_tags ⇒ ActiveRecord::Relation<Tag>
A relation of Tags that are public tags.
- .ransackable_associations(_auth_object = nil) ⇒ Object
-
.ransackable_attributes(_auth_object = nil) ⇒ Object
Ransack configuration.
- .ransortable_attributes(_auth_object = nil) ⇒ Object
-
.search ⇒ ActiveRecord::Relation<Tag>
A relation of Tags that are search.
Instance Method Summary collapse
- #to_param ⇒ Object
- #to_s ⇒ Object
-
#usage_by_type ⇒ Hash
Get usage count by taggable type.
-
#usage_count ⇒ Object
Total usage count (alternative to taggings_count for accuracy).
Methods inherited from ApplicationRecord
ransackable_scopes, #to_relation
Methods included from Models::Schedulable
Methods included from Models::AfterCommittable
Methods included from Models::EventPublishable
Instance Attribute Details
#name ⇒ Object (readonly)
37 |
# File 'app/models/tag.rb', line 37 validates :name, presence: true |
#slug ⇒ Object (readonly)
41 |
# File 'app/models/tag.rb', line 41 validates :slug, uniqueness: true, allow_nil: true |
Class Method Details
.by_taggable_type ⇒ ActiveRecord::Relation<Tag>
A relation of Tags that are by taggable type. Active Record Scope
56 |
# File 'app/models/tag.rb', line 56 scope :by_taggable_type, ->(type) { joins(:taggings).where(taggings: { taggable_type: type }).distinct } |
.canonicalize_input(name) ⇒ Object
Convert human-entered separators to the canonical dash form without
transliterating Unicode or discarding punctuation. The model validation
remains responsible for rejecting everything outside the ASCII domain.
94 95 96 |
# File 'app/models/tag.rb', line 94 def self.canonicalize_input(name) name.to_s.strip.downcase.gsub(/[[:space:]_]+/, '-') end |
.find_or_create_all_by_name(names) ⇒ Array<Tag>
Find or create multiple tags by name
101 102 103 |
# File 'app/models/tag.rb', line 101 def self.find_or_create_all_by_name(names) Array(names).filter_map { |name| find_or_create_by_name(name) } end |
.find_or_create_by_name(name) ⇒ Tag
Find or create a tag by canonical name (case-insensitive).
74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 |
# File 'app/models/tag.rb', line 74 def self.find_or_create_by_name(name) return nil if name.blank? normalized = canonicalize_input(name) find_by(name: normalized) || transaction(requires_new: true) { create!(name: normalized) } rescue ActiveRecord::RecordNotUnique, ActiveRecord::RecordInvalid => e # A concurrent create can lose either the name or slug uniqueness race. # Recover by the dimension that collided, but re-raise unrelated validation # failures instead of silently dropping the tag (AppSignal #1358/#1370). raise e unless NAME_FORMAT.match?(normalized) find_by(slug: normalized) || find_by(name: normalized) || raise(e) end |
.most_used ⇒ ActiveRecord::Relation<Tag>
A relation of Tags that are most used. Active Record Scope
54 |
# File 'app/models/tag.rb', line 54 scope :most_used, -> { order(taggings_count: :desc) } |
.ordered ⇒ ActiveRecord::Relation<Tag>
A relation of Tags that are ordered. Active Record Scope
53 |
# File 'app/models/tag.rb', line 53 scope :ordered, -> { order(:name) } |
.public_tags ⇒ ActiveRecord::Relation<Tag>
A relation of Tags that are public tags. Active Record Scope
55 |
# File 'app/models/tag.rb', line 55 scope :public_tags, -> { where(public: true) } |
.ransackable_associations(_auth_object = nil) ⇒ Object
63 64 65 |
# File 'app/models/tag.rb', line 63 def self.ransackable_associations(_auth_object = nil) %w[taggings] end |
.ransackable_attributes(_auth_object = nil) ⇒ Object
Ransack configuration
59 60 61 |
# File 'app/models/tag.rb', line 59 def self.ransackable_attributes(_auth_object = nil) %w[id name slug public taggings_count created_at updated_at] end |
.ransortable_attributes(_auth_object = nil) ⇒ Object
67 68 69 |
# File 'app/models/tag.rb', line 67 def self.ransortable_attributes(_auth_object = nil) %w[name taggings_count created_at updated_at] end |
.search ⇒ ActiveRecord::Relation<Tag>
A relation of Tags that are search. Active Record Scope
48 49 50 51 52 |
# File 'app/models/tag.rb', line 48 scope :search, ->(query) { return all if query.blank? where('LOWER(name) LIKE LOWER(?)', "%#{sanitize_sql_like(query)}%") } |
Instance Method Details
#activity_types ⇒ ActiveRecord::Relation<ActivityType>
35 |
# File 'app/models/tag.rb', line 35 has_many :activity_types, through: :taggings, source: :taggable, source_type: 'ActivityType' |
#articles ⇒ ActiveRecord::Relation<Article>
Polymorphic associations through taggings
29 |
# File 'app/models/tag.rb', line 29 has_many :articles, through: :taggings, source: :taggable, source_type: 'Article' |
#digital_assets ⇒ ActiveRecord::Relation<DigitalAsset>
31 |
# File 'app/models/tag.rb', line 31 has_many :digital_assets, through: :taggings, source: :taggable, source_type: 'DigitalAsset' |
#floor_plan_displays ⇒ ActiveRecord::Relation<FloorPlanDisplay>
32 |
# File 'app/models/tag.rb', line 32 has_many :floor_plan_displays, through: :taggings, source: :taggable, source_type: 'FloorPlanDisplay' |
#items ⇒ ActiveRecord::Relation<Item>
33 |
# File 'app/models/tag.rb', line 33 has_many :items, through: :taggings, source: :taggable, source_type: 'Item' |
#product_lines ⇒ ActiveRecord::Relation<ProductLine>
34 |
# File 'app/models/tag.rb', line 34 has_many :product_lines, through: :taggings, source: :taggable, source_type: 'ProductLine' |
#showcases ⇒ ActiveRecord::Relation<Showcase>
30 |
# File 'app/models/tag.rb', line 30 has_many :showcases, through: :taggings, source: :taggable, source_type: 'Showcase' |
#taggings ⇒ ActiveRecord::Relation<Tagging>
26 |
# File 'app/models/tag.rb', line 26 has_many :taggings, dependent: :destroy |
#to_param ⇒ Object
120 121 122 |
# File 'app/models/tag.rb', line 120 def to_param slug || id.to_s end |
#to_s ⇒ Object
116 117 118 |
# File 'app/models/tag.rb', line 116 def to_s name end |
#usage_by_type ⇒ Hash
Get usage count by taggable type
107 108 109 |
# File 'app/models/tag.rb', line 107 def usage_by_type taggings.group(:taggable_type).count end |
#usage_count ⇒ Object
Total usage count (alternative to taggings_count for accuracy)
112 113 114 |
# File 'app/models/tag.rb', line 112 def usage_count taggings_count || taggings.count end |