Last active
June 8, 2024 07:53
-
-
Save hara-y-u/e66b69979f79f6dfd2771b50d280e9e9 to your computer and use it in GitHub Desktop.
Scoped Sequential ID Concern for Rails Models
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# 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 |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
This concern is heavily inspired by the awesome sequenced gem.