sequenced 1.3.0 → 1.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- data/CHANGELOG.md +6 -0
- data/README.md +20 -11
- data/lib/sequenced/acts_as_sequenced.rb +10 -1
- data/lib/sequenced/version.rb +1 -1
- data/sequenced.gemspec +3 -3
- data/test/dummy/app/models/rating.rb +3 -0
- data/test/dummy/db/migrate/20130715002029_create_ratings.rb +10 -0
- data/test/dummy/db/schema.rb +61 -27
- data/test/sequenced_test.rb +9 -0
- metadata +12 -8
data/CHANGELOG.md
CHANGED
data/README.md
CHANGED
@@ -23,7 +23,7 @@ end
|
|
23
23
|
|
24
24
|
class Answer < ActiveRecord::Base
|
25
25
|
belongs_to :question
|
26
|
-
acts_as_sequenced :
|
26
|
+
acts_as_sequenced scope: :question_id
|
27
27
|
end
|
28
28
|
```
|
29
29
|
|
@@ -51,18 +51,18 @@ Then, call the `acts_as_sequenced` macro in your model class:
|
|
51
51
|
```ruby
|
52
52
|
class Answer < ActiveRecord::Base
|
53
53
|
belongs_to :question
|
54
|
-
acts_as_sequenced :
|
54
|
+
acts_as_sequenced scope: :question_id
|
55
55
|
end
|
56
56
|
```
|
57
57
|
|
58
|
-
The
|
58
|
+
The `scope` option can be any attribute, but will typically be the foreign
|
59
59
|
key of an associated parent object. You can even scope by multiple columns
|
60
60
|
for polymorphic relationships:
|
61
61
|
|
62
62
|
```ruby
|
63
63
|
class Answer < ActiveRecord::Base
|
64
64
|
belongs_to :questionable, :polymorphic => true
|
65
|
-
acts_as_sequenced :
|
65
|
+
acts_as_sequenced scope: [:questionable_id, :questionable_type]
|
66
66
|
end
|
67
67
|
```
|
68
68
|
|
@@ -72,19 +72,19 @@ end
|
|
72
72
|
|
73
73
|
By default, Sequenced uses the `sequential_id` column and assumes it already
|
74
74
|
exists. If you wish to store the sequential ID in different integer column,
|
75
|
-
simply specify the column name with the
|
75
|
+
simply specify the column name with the `column` option:
|
76
76
|
|
77
77
|
```ruby
|
78
|
-
acts_as_sequenced :
|
78
|
+
acts_as_sequenced scope: :question_id, column: :my_sequential_id
|
79
79
|
```
|
80
80
|
|
81
81
|
### Starting the sequence at a specific number
|
82
82
|
|
83
83
|
By default, Sequenced begins sequences with 1. To start at a different
|
84
|
-
integer, simply set the
|
84
|
+
integer, simply set the `start_at` option:
|
85
85
|
|
86
86
|
```ruby
|
87
|
-
acts_as_sequenced :
|
87
|
+
acts_as_sequenced start_at: 1000
|
88
88
|
```
|
89
89
|
|
90
90
|
### Indexing the sequential ID column
|
@@ -92,6 +92,15 @@ acts_as_sequenced :scope => :question_id, :start_at => 1000
|
|
92
92
|
For optimal performance, it's a good idea to index the sequential ID column
|
93
93
|
on sequenced models.
|
94
94
|
|
95
|
+
### Skipping sequential ID generation
|
96
|
+
|
97
|
+
If you'd like to skip generating a sequential ID under certain conditions,
|
98
|
+
you may pass a lambda to the `skip` option:
|
99
|
+
|
100
|
+
```ruby
|
101
|
+
acts_as_sequenced skip: lambda { |r| r.score == 0 }
|
102
|
+
```
|
103
|
+
|
95
104
|
## Example
|
96
105
|
|
97
106
|
Suppose you have a question model that has many answers. This example
|
@@ -107,7 +116,7 @@ end
|
|
107
116
|
# app/models/answer.rb
|
108
117
|
class Answer < ActiveRecord::Base
|
109
118
|
belongs_to :question
|
110
|
-
acts_as_sequenced :
|
119
|
+
acts_as_sequenced scope: :question_id
|
111
120
|
|
112
121
|
# Automatically use the sequential ID in URLs
|
113
122
|
def to_param
|
@@ -123,7 +132,7 @@ end
|
|
123
132
|
# app/controllers/answers_controller.rb
|
124
133
|
class AnswersController < ApplicationController
|
125
134
|
before_filter :load_question
|
126
|
-
before_filter :load_answer, :
|
135
|
+
before_filter :load_answer, only: [:show, :edit, :update, :destroy]
|
127
136
|
|
128
137
|
private
|
129
138
|
|
@@ -147,7 +156,7 @@ instead of by their primary keys:
|
|
147
156
|
|
148
157
|
## License
|
149
158
|
|
150
|
-
Copyright © 2012 Derrick Reimer
|
159
|
+
Copyright © 2012-2013 Derrick Reimer
|
151
160
|
|
152
161
|
Permission is hereby granted, free of charge, to any person obtaining
|
153
162
|
a copy of this software and associated documentation files (the
|
@@ -18,6 +18,9 @@ module Sequenced
|
|
18
18
|
# sequential ID (default: :sequential_id)
|
19
19
|
# :start_at - The Integer value at which the sequence should
|
20
20
|
# start (default: 1)
|
21
|
+
# :skip - Skips the sequential ID generation when the lambda
|
22
|
+
# expression evaluates to nil. Gets passed the
|
23
|
+
# model object
|
21
24
|
#
|
22
25
|
# Examples
|
23
26
|
#
|
@@ -29,11 +32,12 @@ module Sequenced
|
|
29
32
|
# Returns nothing.
|
30
33
|
def acts_as_sequenced(options = {})
|
31
34
|
# Remove extraneous options
|
32
|
-
options.slice!(:scope, :column, :start_at)
|
35
|
+
options.slice!(:scope, :column, :start_at, :skip)
|
33
36
|
|
34
37
|
# Set defaults
|
35
38
|
options[:column] ||= :sequential_id
|
36
39
|
options[:start_at] ||= 1
|
40
|
+
options[:skip] ||= nil
|
37
41
|
|
38
42
|
# Create class accessor for sequenced options
|
39
43
|
cattr_accessor :sequenced_options
|
@@ -58,6 +62,7 @@ module Sequenced
|
|
58
62
|
def set_sequential_id
|
59
63
|
scope = self.class.sequenced_options[:scope]
|
60
64
|
column = self.class.sequenced_options[:column]
|
65
|
+
skip = self.class.sequenced_options[:skip]
|
61
66
|
|
62
67
|
unless self.respond_to?(column)
|
63
68
|
raise ArgumentError, "Column method ##{column.to_s} is undefined"
|
@@ -66,6 +71,10 @@ module Sequenced
|
|
66
71
|
# Short-circuit here if the ID is already set
|
67
72
|
return unless self.send(column).nil?
|
68
73
|
|
74
|
+
if skip.present?
|
75
|
+
return if skip.call(self)
|
76
|
+
end
|
77
|
+
|
69
78
|
if scope.present?
|
70
79
|
if scope.is_a?(Array)
|
71
80
|
scope.each { |s| verify_scope_method(s) }
|
data/lib/sequenced/version.rb
CHANGED
data/sequenced.gemspec
CHANGED
@@ -13,8 +13,8 @@ Gem::Specification.new do |s|
|
|
13
13
|
s.files = `git ls-files`.split("\n")
|
14
14
|
s.test_files = Dir["test/**/*"]
|
15
15
|
|
16
|
-
s.add_dependency "activesupport", "
|
17
|
-
s.add_dependency "activerecord", "
|
18
|
-
s.add_development_dependency "rails", "
|
16
|
+
s.add_dependency "activesupport", ">= 3.0"
|
17
|
+
s.add_dependency "activerecord", ">= 3.0"
|
18
|
+
s.add_development_dependency "rails", ">= 3.1"
|
19
19
|
s.add_development_dependency "sqlite3"
|
20
20
|
end
|
data/test/dummy/db/schema.rb
CHANGED
@@ -9,66 +9,100 @@
|
|
9
9
|
# from scratch. The latter is a flawed and unsustainable approach (the more migrations
|
10
10
|
# you'll amass, the slower it'll run and the greater likelihood for issues).
|
11
11
|
#
|
12
|
-
# It's strongly recommended
|
12
|
+
# It's strongly recommended that you check this file into your version control system.
|
13
13
|
|
14
|
-
ActiveRecord::Schema.define(:
|
14
|
+
ActiveRecord::Schema.define(version: 20130715002029) do
|
15
15
|
|
16
|
-
create_table "accounts", :
|
16
|
+
create_table "accounts", force: true do |t|
|
17
17
|
t.string "name"
|
18
|
-
t.datetime "created_at"
|
19
|
-
t.datetime "updated_at"
|
18
|
+
t.datetime "created_at"
|
19
|
+
t.datetime "updated_at"
|
20
20
|
end
|
21
21
|
|
22
|
-
create_table "
|
22
|
+
create_table "addresses", force: true do |t|
|
23
|
+
t.integer "account_id"
|
24
|
+
t.string "city"
|
25
|
+
t.datetime "created_at"
|
26
|
+
t.datetime "updated_at"
|
27
|
+
end
|
28
|
+
|
29
|
+
create_table "answers", force: true do |t|
|
23
30
|
t.integer "question_id"
|
24
31
|
t.text "body"
|
25
32
|
t.integer "sequential_id"
|
26
|
-
t.datetime "created_at"
|
27
|
-
t.datetime "updated_at"
|
33
|
+
t.datetime "created_at"
|
34
|
+
t.datetime "updated_at"
|
28
35
|
end
|
29
36
|
|
30
|
-
add_index "answers", ["question_id"], :
|
31
|
-
add_index "answers", ["sequential_id"], :
|
37
|
+
add_index "answers", ["question_id"], name: "index_answers_on_question_id"
|
38
|
+
add_index "answers", ["sequential_id"], name: "index_answers_on_sequential_id"
|
39
|
+
|
40
|
+
create_table "comments", force: true do |t|
|
41
|
+
t.integer "question_id"
|
42
|
+
t.text "body"
|
43
|
+
t.integer "sequential_id"
|
44
|
+
t.datetime "created_at"
|
45
|
+
t.datetime "updated_at"
|
46
|
+
end
|
32
47
|
|
33
|
-
|
48
|
+
add_index "comments", ["question_id"], name: "index_comments_on_question_id"
|
49
|
+
|
50
|
+
create_table "emails", force: true do |t|
|
51
|
+
t.string "emailable_type"
|
52
|
+
t.integer "emailable_id"
|
53
|
+
t.integer "sequential_id"
|
54
|
+
t.string "address"
|
55
|
+
t.datetime "created_at"
|
56
|
+
t.datetime "updated_at"
|
57
|
+
end
|
58
|
+
|
59
|
+
create_table "invoices", force: true do |t|
|
34
60
|
t.integer "amount"
|
35
61
|
t.integer "sequential_id"
|
36
62
|
t.integer "account_id"
|
37
|
-
t.datetime "created_at"
|
38
|
-
t.datetime "updated_at"
|
63
|
+
t.datetime "created_at"
|
64
|
+
t.datetime "updated_at"
|
39
65
|
end
|
40
66
|
|
41
|
-
add_index "invoices", ["account_id"], :
|
67
|
+
add_index "invoices", ["account_id"], name: "index_invoices_on_account_id"
|
42
68
|
|
43
|
-
create_table "orders", :
|
69
|
+
create_table "orders", force: true do |t|
|
44
70
|
t.string "product"
|
45
71
|
t.integer "account_id"
|
46
|
-
t.datetime "created_at"
|
47
|
-
t.datetime "updated_at"
|
72
|
+
t.datetime "created_at"
|
73
|
+
t.datetime "updated_at"
|
48
74
|
end
|
49
75
|
|
50
|
-
create_table "questions", :
|
76
|
+
create_table "questions", force: true do |t|
|
51
77
|
t.string "summary"
|
52
78
|
t.text "body"
|
53
|
-
t.datetime "created_at"
|
54
|
-
t.datetime "updated_at"
|
79
|
+
t.datetime "created_at"
|
80
|
+
t.datetime "updated_at"
|
81
|
+
end
|
82
|
+
|
83
|
+
create_table "ratings", force: true do |t|
|
84
|
+
t.integer "comment_id"
|
85
|
+
t.integer "score"
|
86
|
+
t.integer "sequential_id"
|
87
|
+
t.datetime "created_at"
|
88
|
+
t.datetime "updated_at"
|
55
89
|
end
|
56
90
|
|
57
|
-
create_table "subscriptions", :
|
91
|
+
create_table "subscriptions", force: true do |t|
|
58
92
|
t.string "plan"
|
59
93
|
t.integer "sequential_id"
|
60
|
-
t.datetime "created_at"
|
61
|
-
t.datetime "updated_at"
|
94
|
+
t.datetime "created_at"
|
95
|
+
t.datetime "updated_at"
|
62
96
|
end
|
63
97
|
|
64
|
-
create_table "users", :
|
98
|
+
create_table "users", force: true do |t|
|
65
99
|
t.integer "account_id"
|
66
100
|
t.string "name"
|
67
101
|
t.integer "custom_sequential_id"
|
68
|
-
t.datetime "created_at"
|
69
|
-
t.datetime "updated_at"
|
102
|
+
t.datetime "created_at"
|
103
|
+
t.datetime "updated_at"
|
70
104
|
end
|
71
105
|
|
72
|
-
add_index "users", ["account_id"], :
|
106
|
+
add_index "users", ["account_id"], name: "index_users_on_account_id"
|
73
107
|
|
74
108
|
end
|
data/test/sequenced_test.rb
CHANGED
@@ -10,6 +10,7 @@ require 'test_helper'
|
|
10
10
|
# Address - :scope => :account_id ('sequential_id' does not exist)
|
11
11
|
# Email - :scope => [:emailable_id, :emailable_type]
|
12
12
|
# Subscription - no options
|
13
|
+
# Rating - :scope => :comment_id, skip: { |r| r.score == 0 }
|
13
14
|
|
14
15
|
class SequencedTest < ActiveSupport::TestCase
|
15
16
|
test "default start_at" do
|
@@ -105,4 +106,12 @@ class SequencedTest < ActiveSupport::TestCase
|
|
105
106
|
email = Email.create(:emailable_id => 1, :emailable_type => "User")
|
106
107
|
assert_equal 3, email.sequential_id
|
107
108
|
end
|
109
|
+
|
110
|
+
test "skip option" do
|
111
|
+
rating = Rating.create(:comment_id => 1, :score => 1)
|
112
|
+
assert_equal 1, rating.sequential_id
|
113
|
+
|
114
|
+
rating = Rating.create(:comment_id => 1, :score => 0)
|
115
|
+
assert_equal nil, rating.sequential_id
|
116
|
+
end
|
108
117
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: sequenced
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
4
|
+
version: 1.4.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,14 +9,14 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-
|
12
|
+
date: 2013-07-16 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: activesupport
|
16
16
|
requirement: !ruby/object:Gem::Requirement
|
17
17
|
none: false
|
18
18
|
requirements:
|
19
|
-
- -
|
19
|
+
- - ! '>='
|
20
20
|
- !ruby/object:Gem::Version
|
21
21
|
version: '3.0'
|
22
22
|
type: :runtime
|
@@ -24,7 +24,7 @@ dependencies:
|
|
24
24
|
version_requirements: !ruby/object:Gem::Requirement
|
25
25
|
none: false
|
26
26
|
requirements:
|
27
|
-
- -
|
27
|
+
- - ! '>='
|
28
28
|
- !ruby/object:Gem::Version
|
29
29
|
version: '3.0'
|
30
30
|
- !ruby/object:Gem::Dependency
|
@@ -32,7 +32,7 @@ dependencies:
|
|
32
32
|
requirement: !ruby/object:Gem::Requirement
|
33
33
|
none: false
|
34
34
|
requirements:
|
35
|
-
- -
|
35
|
+
- - ! '>='
|
36
36
|
- !ruby/object:Gem::Version
|
37
37
|
version: '3.0'
|
38
38
|
type: :runtime
|
@@ -40,7 +40,7 @@ dependencies:
|
|
40
40
|
version_requirements: !ruby/object:Gem::Requirement
|
41
41
|
none: false
|
42
42
|
requirements:
|
43
|
-
- -
|
43
|
+
- - ! '>='
|
44
44
|
- !ruby/object:Gem::Version
|
45
45
|
version: '3.0'
|
46
46
|
- !ruby/object:Gem::Dependency
|
@@ -48,7 +48,7 @@ dependencies:
|
|
48
48
|
requirement: !ruby/object:Gem::Requirement
|
49
49
|
none: false
|
50
50
|
requirements:
|
51
|
-
- -
|
51
|
+
- - ! '>='
|
52
52
|
- !ruby/object:Gem::Version
|
53
53
|
version: '3.1'
|
54
54
|
type: :development
|
@@ -56,7 +56,7 @@ dependencies:
|
|
56
56
|
version_requirements: !ruby/object:Gem::Requirement
|
57
57
|
none: false
|
58
58
|
requirements:
|
59
|
-
- -
|
59
|
+
- - ! '>='
|
60
60
|
- !ruby/object:Gem::Version
|
61
61
|
version: '3.1'
|
62
62
|
- !ruby/object:Gem::Dependency
|
@@ -110,6 +110,7 @@ files:
|
|
110
110
|
- test/dummy/app/models/invoice.rb
|
111
111
|
- test/dummy/app/models/order.rb
|
112
112
|
- test/dummy/app/models/question.rb
|
113
|
+
- test/dummy/app/models/rating.rb
|
113
114
|
- test/dummy/app/models/subscription.rb
|
114
115
|
- test/dummy/app/models/user.rb
|
115
116
|
- test/dummy/app/views/layouts/application.html.erb
|
@@ -139,6 +140,7 @@ files:
|
|
139
140
|
- test/dummy/db/migrate/20120219232323_create_addresses.rb
|
140
141
|
- test/dummy/db/migrate/20120220000804_create_comments.rb
|
141
142
|
- test/dummy/db/migrate/20130411225444_create_emails.rb
|
143
|
+
- test/dummy/db/migrate/20130715002029_create_ratings.rb
|
142
144
|
- test/dummy/db/schema.rb
|
143
145
|
- test/dummy/lib/assets/.gitkeep
|
144
146
|
- test/dummy/log/.gitkeep
|
@@ -190,6 +192,7 @@ test_files:
|
|
190
192
|
- test/dummy/app/models/invoice.rb
|
191
193
|
- test/dummy/app/models/order.rb
|
192
194
|
- test/dummy/app/models/question.rb
|
195
|
+
- test/dummy/app/models/rating.rb
|
193
196
|
- test/dummy/app/models/subscription.rb
|
194
197
|
- test/dummy/app/models/user.rb
|
195
198
|
- test/dummy/app/views/layouts/application.html.erb
|
@@ -220,6 +223,7 @@ test_files:
|
|
220
223
|
- test/dummy/db/migrate/20120219232323_create_addresses.rb
|
221
224
|
- test/dummy/db/migrate/20120220000804_create_comments.rb
|
222
225
|
- test/dummy/db/migrate/20130411225444_create_emails.rb
|
226
|
+
- test/dummy/db/migrate/20130715002029_create_ratings.rb
|
223
227
|
- test/dummy/db/schema.rb
|
224
228
|
- test/dummy/db/test.sqlite3
|
225
229
|
- test/dummy/log/development.log
|