class AttrSequence::Generator

Attributes

column[R]
record[R]
scope[R]
skip[R]
start_at[R]

Public Class Methods

new(record, options = {}) click to toggle source
# File lib/attr_sequence/generator.rb, line 5
def initialize(record, options = {})
  @record = record
  @scope = options[:scope]
  @column = options[:column].to_sym
  @start_at = options[:start_at]
  @skip = options[:skip]
end

Public Instance Methods

next_number() click to toggle source
# File lib/attr_sequence/generator.rb, line 27
def next_number
  next_number_in_sequence.tap do |number|
    number += 1 until unique?(number)
  end
end
next_number_in_sequence() click to toggle source
# File lib/attr_sequence/generator.rb, line 33
def next_number_in_sequence
  start_at = self.start_at.respond_to?(:call) ? self.start_at.call(record) : self.start_at
  return start_at unless last_record = find_last_record
  max(last_record.send(column) + 1, start_at)
end
number_set?() click to toggle source
# File lib/attr_sequence/generator.rb, line 19
def number_set?
  !record.send(column).nil?
end
set() click to toggle source
# File lib/attr_sequence/generator.rb, line 13
def set
  return if number_set? || skip?
  lock_table
  record.send(:"#{column}=", next_number)
end
skip?() click to toggle source
# File lib/attr_sequence/generator.rb, line 23
def skip?
  skip && skip.call(record)
end
unique?(number) click to toggle source
# File lib/attr_sequence/generator.rb, line 39
def unique?(number)
  build_scope(*scope) do
    rel = base_relation
    rel = rel.where("NOT number = ?", record.number) if record.persisted?
    rel.where(column => number)
  end.count == 0
end

Private Instance Methods

base_relation() click to toggle source
# File lib/attr_sequence/generator.rb, line 60
def base_relation
  record.class.base_class.unscoped
end
build_scope(*columns) { || ... } click to toggle source
# File lib/attr_sequence/generator.rb, line 72
def build_scope(*columns)
  rel = yield
  columns.each { |c| rel = rel.where(c => record.send(c.to_sym)) }
  rel
end
find_last_record() click to toggle source
# File lib/attr_sequence/generator.rb, line 64
def find_last_record
  build_scope(*scope) do
    base_relation.
    where("#{column.to_s} IS NOT NULL").
    order("#{column.to_s} DESC")
  end.first
end
lock_table() click to toggle source
# File lib/attr_sequence/generator.rb, line 49
def lock_table
  if postgresql?
    record.class.connection.execute("LOCK TABLE #{record.class.table_name} IN EXCLUSIVE MODE")
  end
end
max(*values) click to toggle source
# File lib/attr_sequence/generator.rb, line 78
def max(*values)
  values.to_a.max
end
postgresql?() click to toggle source
# File lib/attr_sequence/generator.rb, line 55
def postgresql?
  defined?(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter) &&
    record.class.connection.instance_of?(ActiveRecord::ConnectionAdapters::PostgreSQLAdapter)
end