Module: Spree::PrefixedId
- Extended by:
- ActiveSupport::Concern
- Included in:
- AdminUserMethods, Base, UserMethods
- Defined in:
- app/models/concerns/spree/prefixed_id.rb
Overview
Adds Stripe-style prefixed IDs to Spree models using Sqids encoding. IDs are computed on the fly from integer primary keys – no database column needed.
e.g., Product with id=12345 -> “prod_86Rf07xd4z”
class Product < Spree.base_class
has_prefix_id :prod
end
Constant Summary collapse
- SQIDS =
Sqids.new(min_length: 10)
Class Method Summary collapse
- .decode_prefixed_id(prefixed_id_string) ⇒ Object
-
.prefixed_id?(value) ⇒ Boolean
Module-level methods for use without a model context (e.g., from ParamsNormalizer).
Instance Method Summary collapse
-
#assign_attributes(new_attributes) ⇒ Object
Automatically resolve prefixed ID strings for belongs_to foreign keys.
-
#prefixed_id ⇒ Object
Returns the Stripe-style prefixed ID, or nil for unsaved records.
-
#to_param ⇒ Object
Use prefixed_id for URL params when available.
Class Method Details
.decode_prefixed_id(prefixed_id_string) ⇒ Object
73 74 75 76 77 78 79 80 81 82 |
# File 'app/models/concerns/spree/prefixed_id.rb', line 73 def self.decode_prefixed_id(prefixed_id_string) return nil if prefixed_id_string.blank? parts = prefixed_id_string.to_s.split('_', 2) return nil if parts.length != 2 _prefix, encoded = parts ids = SQIDS.decode(encoded) ids.first end |
.prefixed_id?(value) ⇒ Boolean
Module-level methods for use without a model context (e.g., from ParamsNormalizer)
69 70 71 |
# File 'app/models/concerns/spree/prefixed_id.rb', line 69 def self.prefixed_id?(value) value.is_a?(String) && value.match?(/\A[a-z]+_[a-zA-Z0-9]+\z/) end |
Instance Method Details
#assign_attributes(new_attributes) ⇒ Object
Automatically resolve prefixed ID strings for belongs_to foreign keys. e.g., product.assign_attributes(tax_category_id: “tc_86Rf07xd4z”) will decode the prefixed ID to the integer primary key.
26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 |
# File 'app/models/concerns/spree/prefixed_id.rb', line 26 def assign_attributes(new_attributes) return super if new_attributes.blank? attrs = new_attributes.to_h needs_resolution = attrs.any? do |key, value| key_s = key.to_s (value.is_a?(String) && key_s.end_with?('_id') && Spree::PrefixedId.prefixed_id?(value)) || (value.is_a?(Array) && key_s.end_with?('_ids') && value.any? { |v| Spree::PrefixedId.prefixed_id?(v) }) end return super unless needs_resolution resolved = attrs.each_with_object({}.with_indifferent_access) do |(key, value), hash| key_s = key.to_s if value.is_a?(String) && key_s.end_with?('_id') && Spree::PrefixedId.prefixed_id?(value) hash[key] = self.class.resolve_prefixed_id_for_attribute(key_s, value) elsif value.is_a?(Array) && key_s.end_with?('_ids') hash[key] = self.class.resolve_prefixed_ids_for_attribute(key_s, value) else hash[key] = value end end super(resolved) end |
#prefixed_id ⇒ Object
Returns the Stripe-style prefixed ID, or nil for unsaved records.
53 54 55 56 57 |
# File 'app/models/concerns/spree/prefixed_id.rb', line 53 def prefixed_id return nil unless id.present? "#{self.class._prefix_id_prefix}_#{Spree::PrefixedId::SQIDS.encode([id])}" end |
#to_param ⇒ Object
Use prefixed_id for URL params when available. Skip if FriendlyId is used (it has its own to_param using slug).
61 62 63 64 65 66 |
# File 'app/models/concerns/spree/prefixed_id.rb', line 61 def to_param return super if self.class.respond_to?(:friendly_id_config) return super unless self.class._prefix_id_prefix.present? prefixed_id.presence || super end |