Class: ContentLink

Inherits:
ApplicationRecord show all
Defined in:
app/models/content_link.rb

Overview

== Schema Information

Table name: content_links
Database name: primary

id :bigint not null, primary key
context :text
created_by_type :string default("manual"), not null
link_type :string not null
position :integer
source_type :string not null
target_type :string not null
created_at :datetime not null
updated_at :datetime not null
source_id :bigint not null
target_id :bigint not null

Indexes

idx_content_links_unique_pair (source_type,source_id,target_type,target_id,link_type) UNIQUE
index_content_links_on_source_type_and_source_id_and_link_type (source_type,source_id,link_type)
index_content_links_on_target_type_and_target_id (target_type,target_id)

Constant Summary collapse

%w[related_post related_video related_showcase related_faq related_publication see_also].freeze
CREATED_BY_TYPES =
%w[manual seo_recommendation sunny].freeze
TARGET_TYPE_CONFIG =

Registry of supported target types — drives the CRM editor dropdowns and lookup URLs.
Keys match polymorphic type as stored by Rails (base class for STI models).
Add entries here as new content types become linkable.

{
  'Article'      => { label: 'Blog Post',    link_type: 'related_post',        display_field: :subject, search_class: 'Post' },
  'DigitalAsset' => { label: 'Video',         link_type: 'related_video',       display_field: :title,   search_class: 'Video' },
  'Showcase'     => { label: 'Showcase',      link_type: 'related_showcase',    display_field: :name },
  'Item'         => { label: 'Publication',   link_type: 'related_publication', display_field: :name,    base_scope: :publications }
}.freeze

Instance Attribute Summary collapse

Belongs to collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods inherited from ApplicationRecord

ransackable_associations, ransackable_attributes, ransackable_scopes, ransortable_attributes, #to_relation

Methods included from Models::EventPublishable

#publish_event

Instance Attribute Details

#created_by_typeObject (readonly)



43
# File 'app/models/content_link.rb', line 43

validates :created_by_type, inclusion: { in: CREATED_BY_TYPES }


42
# File 'app/models/content_link.rb', line 42

validates :link_type, presence: true, inclusion: { in: LINK_TYPES }

#target_idObject (readonly)



44
45
# File 'app/models/content_link.rb', line 44

validates :target_id, uniqueness: { scope: %i[source_type source_id target_type link_type],
message: 'is already linked with this type' }

Class Method Details

.from_sourceActiveRecord::Relation<ContentLink>

A relation of ContentLinks that are from source. Active Record Scope

Returns:

See Also:



50
# File 'app/models/content_link.rb', line 50

scope :from_source, ->(record) { where(source: record) }

.of_typeActiveRecord::Relation<ContentLink>

A relation of ContentLinks that are of type. Active Record Scope

Returns:

See Also:



47
# File 'app/models/content_link.rb', line 47

scope :of_type, ->(type) { where(link_type: type) }

.orderedActiveRecord::Relation<ContentLink>

A relation of ContentLinks that are ordered. Active Record Scope

Returns:

See Also:



48
# File 'app/models/content_link.rb', line 48

scope :ordered, -> { order(Arel.sql('position ASC NULLS LAST, created_at ASC')) }

.targetingActiveRecord::Relation<ContentLink>

A relation of ContentLinks that are targeting. Active Record Scope

Returns:

See Also:



49
# File 'app/models/content_link.rb', line 49

scope :targeting, ->(klass) { where(target_type: klass.to_s) }

Instance Method Details

#created_by_badge_classObject



67
68
69
70
71
72
73
# File 'app/models/content_link.rb', line 67

def created_by_badge_class
  case created_by_type
  when 'seo_recommendation' then 'bg-info'
  when 'sunny' then 'bg-warning text-dark'
  else 'bg-secondary'
  end
end

#created_by_labelObject



59
60
61
62
63
64
65
# File 'app/models/content_link.rb', line 59

def created_by_label
  case created_by_type
  when 'seo_recommendation' then 'SEO'
  when 'sunny' then 'Sunny'
  else 'Manual'
  end
end

#sourceSource

Returns:

See Also:



39
# File 'app/models/content_link.rb', line 39

belongs_to :source, polymorphic: true

#targetTarget

Returns:

  • (Target)

See Also:



40
# File 'app/models/content_link.rb', line 40

belongs_to :target, polymorphic: true

#target_display_nameObject



52
53
54
55
56
57
# File 'app/models/content_link.rb', line 52

def target_display_name
  return 'Unknown' unless target

  field = TARGET_TYPE_CONFIG.dig(target_type, :display_field)
  field ? target.public_send(field) : target.to_s
end