Skip to content

Commit

Permalink
Merge pull request #25 from emaxi/master
Browse files Browse the repository at this point in the history
Possible to pass :scope_by option
  • Loading branch information
celsodantas authored Aug 24, 2016
2 parents f587b75 + 1c4e296 commit bf18bc0
Show file tree
Hide file tree
Showing 10 changed files with 148 additions and 5 deletions.
28 changes: 28 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,30 @@ end
# will produce => "2011HOUSE00001", "2011HOUSE00002"...
```

It's possible to pass :scope_by option as a simple method, Proc.new or lambda

Ex:
```ruby
# :manufacturer should be a Car's instance method(like an ActiveRecord column)
class Car < ActiveRecord::Base
protokoll :code, :scope_by => :manufacturer
end
# will scope Cars by manufacturers, for example "Ford", "Chevrolet"

# :manufacturer and :year should be Car's instance methods(like ActiveRecord columns)
class Car < ActiveRecord::Base
protokoll :code, :scope_by => lambda { |o| "#{o.manufacturer}-#{o.year}" }
end
# will scope Cars by for example "Ford-2016"

# :manufacturer and :year should be Car's instance methods(like ActiveRecord columns)
class Car < ActiveRecord::Base
protokoll :code, :scope_by => Proc.new{ "#{manufacturer}-#{model}" }
end
# will scope Cars by for example "Ford-Mustang", "Chevrolet-Camaro"
```


## reserve_number!

object.reserve_number!
Expand Down Expand Up @@ -116,6 +140,10 @@ Run the generator

rails g protokoll:migration

Optional: If scope_by will be used run next generator as well

rails g protokoll:migration:scope_by

and migrate your database

rake db:migrate
Expand Down
26 changes: 26 additions & 0 deletions lib/generators/protokoll/migration/scope_by_generator.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
require 'rails/generators'

module Protokoll
module Generators
module Migration
class ScopeByGenerator < ::Rails::Generators::Base

include Rails::Generators::Migration

desc "Generate protokoll's scope_by migration"
def create_migration_file
migration_name = "add_scope_by_to_custom_auto_increments.rb"
migration_template migration_name, File.join('db', 'migrate', migration_name)
end

def self.source_root
@source_root ||= File.expand_path(File.join(File.dirname(__FILE__), 'templates'))
end

def self.next_migration_number(path)
Time.now.utc.strftime("%Y%m%d%H%M%S")
end
end
end
end
end
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
class AddScopeByToCustomAutoIncrements < ActiveRecord::Migration
def up
add_column :custom_auto_increments, :counter_model_scope, :string
add_index :custom_auto_increments, [:counter_model_name, :counter_model_scope],
:unique => true, :name => :counter_model_name_scope
end

def down
remove_index :custom_auto_increments, name: :counter_model_name_scope
remove_column :custom_auto_increments, :counter_model_scope, :string
end
end
13 changes: 12 additions & 1 deletion lib/protokoll/counter.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
module Protokoll
class Counter
def self.next(object, options)
element = Models::CustomAutoIncrement.find_or_create_by(counter_model_name: object.class.to_s.underscore)
element = Models::CustomAutoIncrement.find_or_create_by(build_attrs(object, options))

element.counter = options[:start] if outdated?(element, options) || element.counter == 0
element.counter += 1
Expand All @@ -18,6 +18,17 @@ def self.next(object, options)

private

def self.build_attrs(object, options)
attrs = {counter_model_name: object.class.to_s.underscore}
return attrs unless options[:scope_by]

scope_by = options[:scope_by].respond_to?(:call) ?
object.instance_eval(&options[:scope_by]) :
object.send(options[:scope_by])

attrs.merge(counter_model_scope: scope_by)
end

def self.outdated?(record, options)
Time.now.utc.strftime(update_event(options)).to_i > record.updated_at.strftime(update_event(options)).to_i
end
Expand Down
3 changes: 2 additions & 1 deletion lib/protokoll/protokoll.rb
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,8 @@ def protokoll(column, _options = {})
options = { :pattern => "%Y%m#####",
:number_symbol => "#",
:column => column,
:start => 0 }
:start => 0,
:scope_by => nil }

options.merge!(_options)
raise ArgumentError.new("pattern can't be nil!") if options[:pattern].nil?
Expand Down
2 changes: 2 additions & 0 deletions test/dummy/db/migrate/20110923024431_create_protocols.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ class CreateProtocols < ActiveRecord::Migration
def change
create_table :protocols do |t|
t.string :number
t.string :context
t.string :context_2

t.timestamps
end
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
class CreateCustomAutoIncrements < ActiveRecord::Migration
def up
create_table :custom_auto_increments, :force => true do |t|
t.string :counter_model_name
t.string :counter_model_name
t.integer :counter, :default => 0
t.timestamps
end
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
class AddScopeByToCustomAutoIncrements < ActiveRecord::Migration
def up
add_column :custom_auto_increments, :counter_model_scope, :string
add_index :custom_auto_increments, [:counter_model_name, :counter_model_scope],
:unique => true, :name => :counter_model_name_scope
end

def down
remove_index :custom_auto_increments, name: :counter_model_name_scope
remove_column :custom_auto_increments, :counter_model_scope, :string
end
end
8 changes: 6 additions & 2 deletions test/dummy/db/schema.rb
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#
# It's strongly recommended that you check this file into your version control system.

ActiveRecord::Schema.define(version: 20120222164124) do
ActiveRecord::Schema.define(version: 20160310030821) do

create_table "calls", force: :cascade do |t|
t.string "number"
Expand All @@ -21,15 +21,19 @@

create_table "custom_auto_increments", force: :cascade do |t|
t.string "counter_model_name"
t.integer "counter", default: 0
t.integer "counter", default: 0
t.datetime "created_at"
t.datetime "updated_at"
t.string "counter_model_scope"
end

add_index "custom_auto_increments", ["counter_model_name", "counter_model_scope"], name: "counter_model_name_scope", unique: true
add_index "custom_auto_increments", ["counter_model_name"], name: "index_custom_auto_increments_on_counter_model_name"

create_table "protocols", force: :cascade do |t|
t.string "number"
t.string "context"
t.string "context_2"
t.datetime "created_at"
t.datetime "updated_at"
end
Expand Down
47 changes: 47 additions & 0 deletions test/protokoll_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,53 @@ class Protocol < ActiveRecord::Base
assert_equal "2011092601", protocol3.number
end

test "counter should consider instance method scope given" do
class Protocol < ActiveRecord::Base
protokoll :number, :scope_by => :context
end

protocol1 = Protocol.create! context: 'scenario_1'
protocol2 = Protocol.create! context: 'scenario_2'
protocol3 = Protocol.create! context: 'scenario_1'

assert_equal "20110900001", protocol1.number
assert_equal "20110900001", protocol2.number
assert_equal "20110900002", protocol3.number
end

test "counter should consider Proc scope given" do
class Protocol < ActiveRecord::Base
protokoll :number, :scope_by => Proc.new { "#{context}-#{context_2}" }
end

protocol1 = Protocol.create! context: 'scenario_1', context_2: 'case1'
protocol2 = Protocol.create! context: 'scenario_2', context_2: 'case1'
protocol3 = Protocol.create! context: 'scenario_1', context_2: 'case1'
protocol4 = Protocol.create! context: 'scenario_1', context_2: 'case2'

assert_equal "20110900001", protocol1.number
assert_equal "20110900001", protocol2.number
assert_equal "20110900002", protocol3.number
assert_equal "20110900001", protocol4.number
end

test "counter should consider lambda scope given" do
class Protocol < ActiveRecord::Base
protokoll :number, :scope_by => lambda { |o| "#{o.context}-#{o.context_2}" }
end

protocol1 = Protocol.create! context: 'scenario_1', context_2: 'case1'
protocol2 = Protocol.create! context: 'scenario_2', context_2: 'case1'
protocol3 = Protocol.create! context: 'scenario_1', context_2: 'case1'
protocol4 = Protocol.create! context: 'scenario_1', context_2: 'case2'

assert_equal "20110900001", protocol1.number
assert_equal "20110900001", protocol2.number
assert_equal "20110900002", protocol3.number
assert_equal "20110900001", protocol4.number
end


test "rejects empty patterns" do

assert_raise ArgumentError do
Expand Down

0 comments on commit bf18bc0

Please sign in to comment.