Skip to content

Instantly share code, notes, and snippets.

@hara-y-u
Last active June 8, 2024 07:53
Show Gist options
  • Save hara-y-u/e66b69979f79f6dfd2771b50d280e9e9 to your computer and use it in GitHub Desktop.
Save hara-y-u/e66b69979f79f6dfd2771b50d280e9e9 to your computer and use it in GitHub Desktop.
Scoped Sequential ID Concern for Rails Models
# Usage:
# This module adds single scoped sequential id on AR model.
# In your model, include this module like:
# include SequentialId[:number, scope: :user_id]
module SequentialId
def self.[](column_name, scope:)
options = Struct.new(:column_name, :scope)
Module.new do
extend ActiveSupport::Concern
include SequentialId
included do
before_save :set_sequential_id
end
define_method(:sequential_id_options) { options.new(column_name, scope) }
end
end
private
def query_last_sequential_id_value
column_name = sequential_id_options.column_name
scope_column_name = sequential_id_options.scope
scope_condition = { scope_column_name => self[scope_column_name] }
base_relation = self.class.base_class.unscoped
value = base_relation.where(scope_condition).where.not(column_name => nil)
.lock
.order(column_name => :desc).limit(1)
.first&.send(column_name)
value || 0
end
def set_sequential_id
column_name = sequential_id_options.column_name
return if self[column_name]
self[column_name] = query_last_sequential_id_value + 1
end
end
@hara-y-u
Copy link
Author

hara-y-u commented Jun 4, 2024

This concern is heavily inspired by the awesome sequenced gem.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment