Class: SiteMapLink
- Inherits:
-
ApplicationRecord
- Object
- ActiveRecord::Base
- ApplicationRecord
- SiteMapLink
- Defined in:
- app/models/site_map_link.rb
Overview
Represents a directed hyperlink from one SiteMap page to another.
link_type values:
editorial — link placed inside main page content (passes topical signal)
navigation — link found in or .navbar / menu (sitewide template)
footer — link found in (sitewide template)
sidebar — link in an aside / sidebar widget
Template links (navigation, footer) are stored but excluded from gap analysis
and SEO recommendations since they don't carry contextual authority.
== Schema Information
Table name: site_map_links
Database name: primary
id :bigint not null, primary key
anchor_text :string
context_snippet :string
first_seen_at :datetime not null
last_seen_at :datetime not null
link_type :string default("editorial"), not null
to_path :string not null
created_at :datetime not null
updated_at :datetime not null
from_site_map_id :integer not null
to_site_map_id :integer
Indexes
index_site_map_links_on_from_to_path_type (from_site_map_id,to_path,link_type) UNIQUE
index_site_map_links_on_to_path_and_type (to_path,link_type)
index_site_map_links_on_to_site_map_id (to_site_map_id)
Foreign Keys
fk_rails_... (from_site_map_id => site_maps.id) ON DELETE => cascade
fk_rails_... (to_site_map_id => site_maps.id) ON DELETE => cascade
Constant Summary collapse
- LINK_TYPES =
%w[editorial navigation footer sidebar].freeze
Instance Attribute Summary collapse
- #from_site_map_id ⇒ Object readonly
- #link_type ⇒ Object readonly
- #to_path ⇒ Object readonly
Belongs to collapse
Class Method Summary collapse
-
.editorial ⇒ ActiveRecord::Relation<SiteMapLink>
A relation of SiteMapLinks that are editorial.
-
.editorial_to_path ⇒ ActiveRecord::Relation<SiteMapLink>
A relation of SiteMapLinks that are editorial to path.
-
.inbound_to ⇒ ActiveRecord::Relation<SiteMapLink>
A relation of SiteMapLinks that are inbound to.
-
.outbound_from ⇒ ActiveRecord::Relation<SiteMapLink>
A relation of SiteMapLinks that are outbound from.
-
.template ⇒ ActiveRecord::Relation<SiteMapLink>
A relation of SiteMapLinks that are template.
-
.upsert_for_page!(from_site_map, links) ⇒ Object
Bulk upsert links for a page.
Instance Method Summary collapse
-
#editorial? ⇒ Boolean
─── Helpers ───────────────────────────────────────────────────────────────.
- #template? ⇒ Boolean
Methods inherited from ApplicationRecord
ransackable_associations, ransackable_attributes, ransackable_scopes, ransortable_attributes, #to_relation
Methods included from Models::EventPublishable
Instance Attribute Details
#from_site_map_id ⇒ Object (readonly)
47 |
# File 'app/models/site_map_link.rb', line 47 validates :from_site_map_id, uniqueness: { scope: %i[to_path link_type] } |
#link_type ⇒ Object (readonly)
46 |
# File 'app/models/site_map_link.rb', line 46 validates :link_type, inclusion: { in: LINK_TYPES } |
#to_path ⇒ Object (readonly)
45 |
# File 'app/models/site_map_link.rb', line 45 validates :to_path, presence: true |
Class Method Details
.editorial ⇒ ActiveRecord::Relation<SiteMapLink>
A relation of SiteMapLinks that are editorial. Active Record Scope
51 |
# File 'app/models/site_map_link.rb', line 51 scope :editorial, -> { where(link_type: 'editorial') } |
.editorial_to_path ⇒ ActiveRecord::Relation<SiteMapLink>
A relation of SiteMapLinks that are editorial to path. Active Record Scope
57 |
# File 'app/models/site_map_link.rb', line 57 scope :editorial_to_path, ->(path) { editorial.where(to_path: path) } |
.inbound_to ⇒ ActiveRecord::Relation<SiteMapLink>
A relation of SiteMapLinks that are inbound to. Active Record Scope
53 |
# File 'app/models/site_map_link.rb', line 53 scope :inbound_to, ->(site_map) { where(to_site_map_id: site_map.id) } |
.outbound_from ⇒ ActiveRecord::Relation<SiteMapLink>
A relation of SiteMapLinks that are outbound from. Active Record Scope
54 |
# File 'app/models/site_map_link.rb', line 54 scope :outbound_from, ->(site_map) { where(from_site_map_id: site_map.id) } |
.template ⇒ ActiveRecord::Relation<SiteMapLink>
A relation of SiteMapLinks that are template. Active Record Scope
52 |
# File 'app/models/site_map_link.rb', line 52 scope :template, -> { where(link_type: %w[navigation footer]) } |
.upsert_for_page!(from_site_map, links) ⇒ Object
Bulk upsert links for a page. Existing rows are updated (anchor, last_seen_at);
new rows are inserted. Rows no longer present in the crawl are not deleted —
they get stale naturally and can be pruned separately if needed.
67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 |
# File 'app/models/site_map_link.rb', line 67 def self.upsert_for_page!(from_site_map, links) return if links.blank? now = Time.current # Resolve to_site_map_id for each target path (batch lookup) paths = links.map { |l| l[:to_path] }.uniq.compact path_to_id = SiteMap.where(path: paths, locale: from_site_map.locale) .pluck(:path, :id) .to_h rows = links.map do |link| { from_site_map_id: from_site_map.id, to_path: link[:to_path], to_site_map_id: path_to_id[link[:to_path]], anchor_text: link[:anchor_text].to_s.truncate(255), link_type: link[:link_type] || 'editorial', context_snippet: link[:context_snippet].to_s.truncate(200), first_seen_at: now, last_seen_at: now, created_at: now, updated_at: now } end upsert_all( rows, unique_by: %i[from_site_map_id to_path link_type], update_only: %i[to_site_map_id anchor_text context_snippet last_seen_at] ) end |
Instance Method Details
#editorial? ⇒ Boolean
─── Helpers ───────────────────────────────────────────────────────────────
102 |
# File 'app/models/site_map_link.rb', line 102 def editorial? = link_type == 'editorial' |
#from_site_map ⇒ SiteMap
42 |
# File 'app/models/site_map_link.rb', line 42 belongs_to :from_site_map, class_name: 'SiteMap' |
#template? ⇒ Boolean
103 |
# File 'app/models/site_map_link.rb', line 103 def template? = %w[navigation footer].include?(link_type) |
#to_site_map ⇒ SiteMap
43 |
# File 'app/models/site_map_link.rb', line 43 belongs_to :to_site_map, class_name: 'SiteMap', optional: true |