Skip to content

Commit

Permalink
Merge pull request #19 from samphilipd/sam/multiple_sequences
Browse files Browse the repository at this point in the history
Multiple sequences, first draft with simple test
  • Loading branch information
derrickreimer committed Jan 23, 2016
2 parents 2591226 + 4e4c54e commit b5d5f53
Show file tree
Hide file tree
Showing 6 changed files with 115 additions and 20 deletions.
39 changes: 33 additions & 6 deletions lib/sequenced/acts_as_sequenced.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,12 @@

module Sequenced
module ActsAsSequenced
DEFAULT_OPTIONS = {
column: :sequential_id,
start_at: 1
}.freeze
SequencedColumnExists = Class.new(StandardError)

def self.included(base)
base.extend ClassMethods
end
Expand All @@ -11,6 +17,8 @@ module ClassMethods
# Public: Defines ActiveRecord callbacks to set a sequential ID scoped
# on a specific class.
#
# Can be called multiple times to add hooks for different column names.
#
# options - The Hash of options for configuration:
# :scope - The Symbol representing the columm on which the
# sequential ID should be scoped (default: nil)
Expand All @@ -31,17 +39,36 @@ module ClassMethods
#
# Returns nothing.
def acts_as_sequenced(options = {})
cattr_accessor :sequenced_options
self.sequenced_options = options
unless defined?(sequenced_options)
include Sequenced::ActsAsSequenced::InstanceMethods

mattr_accessor :sequenced_options, instance_accessor: false do
[]
end

before_save :set_sequential_ids
end

options = DEFAULT_OPTIONS.merge(options)
column_name = options[:column]

before_save :set_sequential_id
include Sequenced::ActsAsSequenced::InstanceMethods
if sequenced_options.any? {|options| options[:column] == column_name}
raise(SequencedColumnExists, <<-MSG.squish)
Tried to set #{column_name} as sequenced but there was already a
definition here. Did you accidentally call acts_as_sequenced
multiple times on the same column?
MSG
else
sequenced_options << options
end
end
end

module InstanceMethods
def set_sequential_id
Sequenced::Generator.new(self, self.class.base_class.sequenced_options).set
def set_sequential_ids
self.class.base_class.sequenced_options.each do |options|
Sequenced::Generator.new(self, options).set
end
end
end
end
Expand Down
4 changes: 2 additions & 2 deletions lib/sequenced/generator.rb
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@ class Generator
def initialize(record, options = {})
@record = record
@scope = options[:scope]
@column = (options[:column] || :sequential_id).to_sym
@start_at = options[:start_at] || 1
@column = options[:column].to_sym
@start_at = options[:start_at]
@skip = options[:skip]
end

Expand Down
4 changes: 4 additions & 0 deletions test/dummy/app/models/doppelganger.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
class Doppelganger < ActiveRecord::Base
acts_as_sequenced column: :sequential_id_one
acts_as_sequenced column: :sequential_id_two, start_at: 1000
end
10 changes: 10 additions & 0 deletions test/dummy/db/migrate/20160118182655_create_doppelgangers.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
class CreateDoppelgangers < ActiveRecord::Migration
def change
create_table :doppelgangers do |t|
t.integer :sequential_id_one
t.integer :sequential_id_two

t.timestamps null: false
end
end
end
58 changes: 46 additions & 12 deletions test/dummy/db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,22 +11,22 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 20130715002029) do
ActiveRecord::Schema.define(version: 20160118182655) do

create_table "accounts", force: true do |t|
create_table "accounts", force: :cascade do |t|
t.string "name"
t.datetime "created_at"
t.datetime "updated_at"
end

create_table "addresses", force: true do |t|
create_table "addresses", force: :cascade do |t|
t.integer "account_id"
t.string "city"
t.datetime "created_at"
t.datetime "updated_at"
end

create_table "answers", force: true do |t|
create_table "answers", force: :cascade do |t|
t.integer "question_id"
t.text "body"
t.integer "sequential_id"
Expand All @@ -37,7 +37,7 @@
add_index "answers", ["question_id"], name: "index_answers_on_question_id"
add_index "answers", ["sequential_id"], name: "index_answers_on_sequential_id"

create_table "comments", force: true do |t|
create_table "comments", force: :cascade do |t|
t.integer "question_id"
t.text "body"
t.integer "sequential_id"
Expand All @@ -47,7 +47,21 @@

add_index "comments", ["question_id"], name: "index_comments_on_question_id"

create_table "emails", force: true do |t|
create_table "concurrent_badgers", force: :cascade do |t|
t.integer "sequential_id", null: false
t.integer "burrow_id"
end

add_index "concurrent_badgers", ["sequential_id", "burrow_id"], name: "unique_concurrent", unique: true

create_table "doppelgangers", force: :cascade do |t|
t.integer "sequential_id_one"
t.integer "sequential_id_two"
t.datetime "created_at", null: false
t.datetime "updated_at", null: false
end

create_table "emails", force: :cascade do |t|
t.string "emailable_type"
t.integer "emailable_id"
t.integer "sequential_id"
Expand All @@ -56,7 +70,7 @@
t.datetime "updated_at"
end

create_table "invoices", force: true do |t|
create_table "invoices", force: :cascade do |t|
t.integer "amount"
t.integer "sequential_id"
t.integer "account_id"
Expand All @@ -66,36 +80,56 @@

add_index "invoices", ["account_id"], name: "index_invoices_on_account_id"

create_table "orders", force: true do |t|
create_table "monsters", force: :cascade do |t|
t.integer "sequential_id"
t.string "type"
t.datetime "created_at"
t.datetime "updated_at"
end

create_table "orders", force: :cascade do |t|
t.string "product"
t.integer "account_id"
t.datetime "created_at"
t.datetime "updated_at"
end

create_table "questions", force: true do |t|
create_table "policemen", force: :cascade do |t|
t.integer "sequential_id"
t.datetime "created_at"
t.datetime "updated_at"
end

create_table "products", force: :cascade do |t|
t.integer "account_id"
t.integer "sequential_id"
t.datetime "created_at"
t.datetime "updated_at"
end

create_table "questions", force: :cascade do |t|
t.string "summary"
t.text "body"
t.datetime "created_at"
t.datetime "updated_at"
end

create_table "ratings", force: true do |t|
create_table "ratings", force: :cascade do |t|
t.integer "comment_id"
t.integer "score"
t.integer "sequential_id"
t.datetime "created_at"
t.datetime "updated_at"
end

create_table "subscriptions", force: true do |t|
create_table "subscriptions", force: :cascade do |t|
t.string "plan"
t.integer "sequential_id"
t.datetime "created_at"
t.datetime "updated_at"
end

create_table "users", force: true do |t|
create_table "users", force: :cascade do |t|
t.integer "account_id"
t.string "name"
t.integer "custom_sequential_id"
Expand Down
20 changes: 20 additions & 0 deletions test/multiple_sequences_test.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
require 'test_helper'

class MultipleSequencesTest < ActiveSupport::TestCase
test "works with simple multiple sequences" do
doppelganger = Doppelganger.create!
assert_equal 1, doppelganger.sequential_id_one
assert_equal 1000, doppelganger.sequential_id_two
end

test "raises error on multiple definitions for the same column" do
assert_raise Sequenced::ActsAsSequenced::SequencedColumnExists do
Doppelganger.class_eval do
acts_as_sequenced column: :sequential_id_one, start_at: 99
end
end

doppelganger = Doppelganger.create!
assert_equal 1, doppelganger.sequential_id_one
end
end

0 comments on commit b5d5f53

Please sign in to comment.