Class: Decidim::ShortLink
- Inherits:
-
ApplicationRecord
- Object
- ActiveRecord::Base
- ApplicationRecord
- Decidim::ShortLink
- Defined in:
- decidim-core/app/models/decidim/short_link.rb
Overview
Short links are a way to reference specific locations within Decidim with shorted URLs, similar to the popular link shortening services. The original reason for creating the feature was to reference long calendar URLs in a more compact way for the URLs to be compatible with the calendar programs. When the URL is long with lots of filtering parameters included in it, it may be too long for specific 3rd party programs.
This feature can be used to link to any URLs or resources in Decidim with a short reference.
Defined Under Namespace
Classes: OutOfCandidatesError
Class Method Summary collapse
-
.to(target, mounted_engine, route_name: nil, params: {}) ⇒ Decidim::ShortLink
Finds a matching short link to the same target with exactly the same parameters if it already exists or creates a new one if it does not exist.
-
.unique_identifier_within(organization) ⇒ String
Creates a random unique identifier for any new links.
Instance Method Summary collapse
-
#route_name ⇒ String
Overrides the route_name method to add a default route name for the “root” path in case the route name is not defined for the record.
-
#short_url ⇒ String
Generates the short URL referencing this link.
-
#target_url ⇒ String
Generates the full long URL to the resource matching this short link.
Class Method Details
.to(target, mounted_engine, route_name: nil, params: {}) ⇒ Decidim::ShortLink
Finds a matching short link to the same target with exactly the same parameters if it already exists or creates a new one if it does not exist.
35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 |
# File 'decidim-core/app/models/decidim/short_link.rb', line 35 def self.to(target, mounted_engine, route_name: nil, params: {}) organization = if target.is_a?(Decidim::Organization) target else target.try(:organization) end values = { organization:, target:, mounted_engine_name: mounted_engine, route_name: } existing = if params where(values).find_by("params = ?::jsonb", params.to_json) else find_by(values.merge(params: nil)) end existing || create!(values.merge(params:)) end |
.unique_identifier_within(organization) ⇒ String
Creates a random unique identifier for any new links. Raises an OutOfCandidatesError if a free candidate cannot be found with 20 tries. In this situation the older records should be removed from the database.
64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'decidim-core/app/models/decidim/short_link.rb', line 64 def self.unique_identifier_within(organization) 1.step do |n| raise OutOfCandidatesError if n > 20 # A-Z, a-z and 0-9 # 26 + 26 + 10 = 62 possibilities per character # 62^10 ≈ 8×10¹⁷ total possibilities candidate = SecureRandom.alphanumeric(10) next if where(organization:, identifier: candidate).any? return candidate end end |
Instance Method Details
#route_name ⇒ String
Overrides the route_name method to add a default route name for the “root” path in case the route name is not defined for the record.
82 83 84 |
# File 'decidim-core/app/models/decidim/short_link.rb', line 82 def route_name super || "root" end |
#short_url ⇒ String
Generates the short URL referencing this link.
89 90 91 |
# File 'decidim-core/app/models/decidim/short_link.rb', line 89 def short_url EngineRouter.new("decidim", ).short_link_url(id: identifier) end |
#target_url ⇒ String
Generates the full long URL to the resource matching this short link.
96 97 98 |
# File 'decidim-core/app/models/decidim/short_link.rb', line 96 def target_url url_helpers.send("#{route_name}_url", **params) end |