module ActiveRecord::Integration

def cache_key

Product.find(5).cache_key # => "products/5-20071224150000" (updated_at available)
Product.cache_versioning = false

the cache key will also include a version.
If ActiveRecord::Base.cache_versioning is turned off, as it was in Rails 5.1 and earlier,

Product.find(5).cache_key # => "products/5"
Product.new.cache_key # => "products/new"

Returns a stable cache key that can be used to identify this record.
def cache_key
  if new_record?
    "#{model_name.cache_key}/new"
  else
    if cache_version
      "#{model_name.cache_key}/#{id}"
    else
      timestamp = max_updated_column_timestamp
      if timestamp
        timestamp = timestamp.utc.to_fs(cache_timestamp_format)
        "#{model_name.cache_key}/#{id}-#{timestamp}"
      else
        "#{model_name.cache_key}/#{id}"
      end
    end
  end
end

def cache_key_with_version

Returns a cache key along with the version.
def cache_key_with_version
  if version = cache_version
    "#{cache_key}-#{version}"
  else
    cache_key
  end
end

def cache_version

+false+.
Note, this method will return nil if ActiveRecord::Base.cache_versioning is set to

cache_version, but this method can be overwritten to return something else.
a recyclable caching scheme. By default, the #updated_at column is used for the
Returns a cache version that can be used together with the cache key to form
def cache_version
  return unless cache_versioning
  if has_attribute?("updated_at")
    timestamp = updated_at_before_type_cast
    if can_use_fast_cache_version?(timestamp)
      raw_timestamp_to_cache_version(timestamp)
    elsif timestamp = updated_at
      timestamp.utc.to_fs(cache_timestamp_format)
    end
  elsif self.class.has_attribute?("updated_at")
    raise ActiveModel::MissingAttributeError, "missing attribute: updated_at"
  end
end

def can_use_fast_cache_version?(timestamp)

we cannot apply our transformations correctly.
or if the timezone is not set to UTC then
We also must check if the timestamp format has been changed

string value directly from the database.
The fast cache version only works with a

can be used to generate a cache_version.
Detects if the value before type cast
def can_use_fast_cache_version?(timestamp)
  timestamp.is_a?(String) &&
    cache_timestamp_format == :usec &&
    ActiveRecord.default_timezone == :utc &&
    !updated_at_came_from_user?
end

def raw_timestamp_to_cache_version(timestamp)

to account for this we pad the output with zeros
https://github.com/postgres/postgres/commit/3e1beda2cde3495f41290e1ece5d544525810214
PostgreSQL truncates trailing zeros,

# => "20181015200215266505"
raw_timestamp_to_cache_version(timestamp)
timestamp = "2018-10-15 20:02:15.266505"

Example:

format.
Converts a raw database string to `:usec`
def raw_timestamp_to_cache_version(timestamp)
  key = timestamp.delete("- :.")
  if key.length < 20
    key.ljust(20, "0")
  else
    key
  end
end

def to_param

user_path(user) # => "/users/Phusion"
user = User.find_by(name: 'Phusion')

end
end
name
def to_param # overridden
class User < ActiveRecord::Base

a path using the user's name instead of the user's id:
You can override +to_param+ in your model to make +user_path+ construct

user_path(user) # => "/users/1"
user = User.find_by(name: 'Phusion')

construct a path with the user object's 'id' in it:
resources :users route. Normally, +user_path+ will
For example, suppose that you have a User model, and that you have a

or +nil+ if this record's unsaved.
object. The default implementation returns this record's id as a +String+,
Returns a +String+, which Action Pack uses for constructing a URL to this
def to_param
  # We can't use alias_method here, because method 'id' optimizes itself on the fly.
  id && id.to_s # Be sure to stringify the id for routes
end