openstax_utilities 1.1.0 → 1.2.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.
- checksums.yaml +15 -0
- data/app/helpers/openstax/utilities/osu_helper.rb +1 -0
- data/lib/openstax/utilities/active_record_extensions.rb +14 -0
- data/lib/openstax/utilities/acts_as_numberable.rb +218 -0
- data/lib/openstax/utilities/delegate_access_control.rb +51 -0
- data/lib/openstax/utilities/helpers/misc.rb +9 -0
- data/lib/openstax/utilities/version.rb +1 -1
- data/lib/openstax_utilities.rb +4 -0
- metadata +15 -23
checksums.yaml
ADDED
@@ -0,0 +1,15 @@
|
|
1
|
+
---
|
2
|
+
!binary "U0hBMQ==":
|
3
|
+
metadata.gz: !binary |-
|
4
|
+
Yzc2ZjE5YTExNmU0YjkzYWRmMTgwYzQyYjJjOWYzMDE5Nzk2OWI4ZQ==
|
5
|
+
data.tar.gz: !binary |-
|
6
|
+
NDdhMjA5NDJiOWM4YmM3MzNiNWE2NWE3Nzk5ZmRlYzJiY2FlOTZhOA==
|
7
|
+
SHA512:
|
8
|
+
metadata.gz: !binary |-
|
9
|
+
MzI4MzM2MDBlN2U2MmNiYzU1ODk3NTA5NmExOWJlZTkyOTdhOGQ0OGQxNWMx
|
10
|
+
Nzg5Y2UxNDNhOTc5NWFkYzIwMDkzZDI5YjRjNzcwMWNiOWRlYWY2YjExMDE5
|
11
|
+
YTViOWUzZTY5NDRiZDFmODJjZGY5MjllOGMxZmY4ZDJhNmM0NmY=
|
12
|
+
data.tar.gz: !binary |-
|
13
|
+
N2NjNWY2MTQzMDNmZjRiMTYxM2U0MzQ4NTQxMzQ5Y2Q2MDdiYWQ4YzA4OTc4
|
14
|
+
ZGEzODA2YTdiYmY5ZTlhNGE0MDhmNjk1NjFjNDVmYTkzOGU5MDRlMjQ3NzFi
|
15
|
+
ZjRjMWFiNGUwZDg5Y2RmMDhlNGFjZTk3MWQwNWMwMDQ5ZTg2MzI=
|
@@ -3,6 +3,7 @@ module OpenStax::Utilities
|
|
3
3
|
|
4
4
|
def osu
|
5
5
|
@@osu_class ||= Class.new(ClassyHelper) do
|
6
|
+
include OpenStax::Utilities::Helpers::Misc
|
6
7
|
include OpenStax::Utilities::Helpers::Blocks
|
7
8
|
include OpenStax::Utilities::Helpers::Partials
|
8
9
|
include OpenStax::Utilities::Helpers::ActionList
|
@@ -0,0 +1,218 @@
|
|
1
|
+
# Copyright 2011-2012 Rice University. Licensed under the Affero General Public
|
2
|
+
# License version 3 or later. See the COPYRIGHT file for details.
|
3
|
+
|
4
|
+
module OpenStax
|
5
|
+
module Utilities
|
6
|
+
|
7
|
+
module ActsAsNumberable
|
8
|
+
|
9
|
+
# Adds code to an ActiveRecord object so that it can be sorted.
|
10
|
+
# @example Model is ordered globally using a 'number' field
|
11
|
+
# class MyModel < ActiveRecord::Base
|
12
|
+
# acts_as_numberable
|
13
|
+
# @example Model is ordered globally using a 'position' field
|
14
|
+
# class MyModel < ActiveRecord::Base
|
15
|
+
# acts_as_numberable :number_field => :position
|
16
|
+
# @example Model is ordered within a container class using a position field
|
17
|
+
# class MyModel < ActiveRecord::Base
|
18
|
+
# belongs_to :other_model
|
19
|
+
# acts_as_numberable :container => :other_model,
|
20
|
+
# :number_field => :position
|
21
|
+
# @param :container The relationship that contains this model in an order.
|
22
|
+
# Note that this code assumes the foreign key for this container is found
|
23
|
+
# by appending "_id" onto the container name, which might not always be the
|
24
|
+
# case.
|
25
|
+
# @param :number_field The column to use as the sorting number, given either
|
26
|
+
# as a string or a symbol. The default is 'number'
|
27
|
+
# @param :table_class By default this code assumes that the database table
|
28
|
+
# name to use for this model can be derived from the model's class name; in
|
29
|
+
# some cases (e.g. STI) this is not the case and this parameter can be used
|
30
|
+
# to manually specify the class from which to derive the database table name.
|
31
|
+
#
|
32
|
+
def acts_as_numberable(options={})
|
33
|
+
configuration = {}
|
34
|
+
configuration.update(options) if options.is_a?(Hash)
|
35
|
+
|
36
|
+
container_column = nil
|
37
|
+
container_column_symbol = nil
|
38
|
+
|
39
|
+
# When calling assign_number below, you normally want to run a query against
|
40
|
+
# self.class to figure out what the next available number is; however, if the
|
41
|
+
# class acting as numberable is using STI, self.class will return the child class
|
42
|
+
# which is likely not what we want. In these cases, we can specify the base
|
43
|
+
# class here (the class that has the same name as the DB table) so that it is used
|
44
|
+
# instead.
|
45
|
+
table_class = configuration[:table_class]
|
46
|
+
|
47
|
+
number_field = (configuration[:number_field] || 'number').to_s
|
48
|
+
|
49
|
+
if !configuration[:container].nil?
|
50
|
+
container_column = configuration[:container].to_s + "_id"
|
51
|
+
container_column_symbol = configuration[:container].to_sym
|
52
|
+
end
|
53
|
+
|
54
|
+
uniqueness_scope_string = container_column.nil? ? "" : ":scope => :#{container_column},"
|
55
|
+
|
56
|
+
class_eval <<-EOV
|
57
|
+
include ActsAsNumberable::BasicInstanceMethods
|
58
|
+
|
59
|
+
before_validation :assign_number, :on => :create
|
60
|
+
|
61
|
+
validates :#{number_field}, :uniqueness => { #{uniqueness_scope_string}
|
62
|
+
:allow_nil => true},
|
63
|
+
:numericality => { :only_integer => true,
|
64
|
+
:greater_than_or_equal_to => 0,
|
65
|
+
:allow_nil => true }
|
66
|
+
|
67
|
+
|
68
|
+
after_destroy :mark_as_destroyed
|
69
|
+
|
70
|
+
attr_accessor :destroyed
|
71
|
+
attr_accessor :changed_sets
|
72
|
+
|
73
|
+
attr_protected :#{number_field}
|
74
|
+
|
75
|
+
scope :ordered, order('#{number_field} ASC')
|
76
|
+
scope :reverse_ordered, order('#{number_field} DESC')
|
77
|
+
|
78
|
+
def self.sort!(sorted_ids)
|
79
|
+
return if sorted_ids.blank?
|
80
|
+
items = []
|
81
|
+
ActiveRecord::Base.transaction do
|
82
|
+
items = find_in_specified_order(sorted_ids)
|
83
|
+
|
84
|
+
items.each do |item|
|
85
|
+
item.send('#{number_field}=', nil)
|
86
|
+
item.save!
|
87
|
+
end
|
88
|
+
|
89
|
+
items.each_with_index do |item, ii|
|
90
|
+
item.send('#{number_field}=', ii)
|
91
|
+
item.save!
|
92
|
+
end
|
93
|
+
end
|
94
|
+
items
|
95
|
+
end
|
96
|
+
|
97
|
+
def table_class
|
98
|
+
#{table_class}
|
99
|
+
end
|
100
|
+
|
101
|
+
def number_field
|
102
|
+
'#{number_field}'
|
103
|
+
end
|
104
|
+
EOV
|
105
|
+
|
106
|
+
|
107
|
+
if !configuration[:container].nil?
|
108
|
+
class_eval <<-EOV
|
109
|
+
include ActsAsNumberable::ContainerInstanceMethods
|
110
|
+
|
111
|
+
# When we had nested acts_as_numberables, there were cases where the
|
112
|
+
# objects were having their numbers changed (as their peers were being
|
113
|
+
# removed from the container), but then when it came time to delete those
|
114
|
+
# objects they still had their old number. So just reload before
|
115
|
+
# destroy.
|
116
|
+
before_destroy(prepend: true) {self.reload}
|
117
|
+
|
118
|
+
after_destroy :remove_from_container!
|
119
|
+
|
120
|
+
def container_column
|
121
|
+
'#{container_column}'
|
122
|
+
end
|
123
|
+
|
124
|
+
def container
|
125
|
+
'#{configuration[:container]}'
|
126
|
+
end
|
127
|
+
|
128
|
+
def table_class
|
129
|
+
#{table_class}
|
130
|
+
end
|
131
|
+
|
132
|
+
EOV
|
133
|
+
|
134
|
+
end
|
135
|
+
|
136
|
+
end
|
137
|
+
|
138
|
+
module BasicInstanceMethods
|
139
|
+
protected
|
140
|
+
|
141
|
+
def my_class
|
142
|
+
table_class || self.class
|
143
|
+
end
|
144
|
+
|
145
|
+
def assign_number
|
146
|
+
self.send("#{number_field}=", my_class.count) if self.send("#{number_field}").nil?
|
147
|
+
end
|
148
|
+
|
149
|
+
def mark_as_destroyed
|
150
|
+
destroyed = true
|
151
|
+
end
|
152
|
+
|
153
|
+
def me_and_peers
|
154
|
+
my_class.scoped
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
158
|
+
module ContainerInstanceMethods
|
159
|
+
def move_to_container!(new_container)
|
160
|
+
return if new_container.id == self.send(container_column)
|
161
|
+
ActiveRecord::Base.transaction do
|
162
|
+
remove_from_container!
|
163
|
+
|
164
|
+
self.send container + "=", new_container
|
165
|
+
|
166
|
+
self.assign_number
|
167
|
+
self.save!
|
168
|
+
self.changed_sets = true
|
169
|
+
end
|
170
|
+
end
|
171
|
+
|
172
|
+
def remove_from_container!
|
173
|
+
later_items = my_class.where(container_column => self.send(container_column))
|
174
|
+
.where("#{number_field} > ?", self.send(number_field))
|
175
|
+
|
176
|
+
if !self.destroyed
|
177
|
+
self.send "#{number_field}=", nil
|
178
|
+
self.send container_column + '=', nil
|
179
|
+
self.save!
|
180
|
+
end
|
181
|
+
|
182
|
+
# Do this to make sure that the reordering below doesn't
|
183
|
+
# cause a number to be duplicated temporarily (which would
|
184
|
+
# cause a validation error)
|
185
|
+
later_items.sort_by!{|item| item.send(number_field)}
|
186
|
+
|
187
|
+
later_items.each do |later|
|
188
|
+
later.send("#{number_field}=", later.send(number_field)-1)
|
189
|
+
later.save!
|
190
|
+
end
|
191
|
+
end
|
192
|
+
|
193
|
+
def my_class
|
194
|
+
table_class || self.class
|
195
|
+
end
|
196
|
+
|
197
|
+
def me_and_peers
|
198
|
+
my_class.where(container_column => self.send(container_column))
|
199
|
+
end
|
200
|
+
|
201
|
+
protected
|
202
|
+
|
203
|
+
def assign_number
|
204
|
+
if self.send(number_field).nil?
|
205
|
+
self.send("#{number_field}=",
|
206
|
+
my_class
|
207
|
+
.where(container_column => self.send(container_column))
|
208
|
+
.count)
|
209
|
+
end
|
210
|
+
end
|
211
|
+
end
|
212
|
+
|
213
|
+
end
|
214
|
+
|
215
|
+
end
|
216
|
+
end
|
217
|
+
|
218
|
+
ActiveRecord::Base.extend OpenStax::Utilities::ActsAsNumberable
|
@@ -0,0 +1,51 @@
|
|
1
|
+
# Copyright 2011-2012 Rice University. Licensed under the Affero General Public
|
2
|
+
# License version 3 or later. See the COPYRIGHT file for details.
|
3
|
+
|
4
|
+
module OpenStax
|
5
|
+
module Utilities
|
6
|
+
|
7
|
+
module DelegateAccessControl
|
8
|
+
|
9
|
+
# Adds code to an ActiveRecord object to delegate its access control methods to
|
10
|
+
# another object.
|
11
|
+
# @example Model is ordered globally using a 'number' field
|
12
|
+
# class MyModel < ActiveRecord::Base
|
13
|
+
# belongs_to :another
|
14
|
+
# delegate_access_control to: :another
|
15
|
+
# @param :to The relationship to which the access control methods should
|
16
|
+
# be delegated.
|
17
|
+
# @param :include_sort If true, a "can_be_sorted_by?" method will be included
|
18
|
+
# (Default: false)
|
19
|
+
#
|
20
|
+
def delegate_access_control(options={})
|
21
|
+
configuration = {include_sort: false}
|
22
|
+
configuration.update(options) if options.is_a?(Hash)
|
23
|
+
|
24
|
+
raise IllegalArgument, "A :to option must be provided" if configuration[:to].blank?
|
25
|
+
|
26
|
+
configuration[:to] = configuration[:to].to_s
|
27
|
+
|
28
|
+
class_eval <<-EOV
|
29
|
+
delegate :can_be_read_by?,
|
30
|
+
:can_be_updated_by?,
|
31
|
+
to: :#{configuration[:to]}
|
32
|
+
|
33
|
+
# Delegating creation and destroying of this contained object means you can
|
34
|
+
# update the containing object
|
35
|
+
|
36
|
+
alias_method :can_be_created_by?, :can_be_updated_by?
|
37
|
+
alias_method :can_be_destroyed_by?, :can_be_updated_by?
|
38
|
+
|
39
|
+
if #{configuration[:include_sort]}
|
40
|
+
alias_method :can_be_sorted_by?, :can_be_updated_by?
|
41
|
+
end
|
42
|
+
EOV
|
43
|
+
|
44
|
+
end
|
45
|
+
|
46
|
+
end
|
47
|
+
|
48
|
+
end
|
49
|
+
end
|
50
|
+
|
51
|
+
ActiveRecord::Base.extend OpenStax::Utilities::DelegateAccessControl
|
data/lib/openstax_utilities.rb
CHANGED
@@ -8,6 +8,7 @@ OSU = OpenStax::Utilities
|
|
8
8
|
require "openstax/utilities/engine"
|
9
9
|
require "openstax/utilities/version"
|
10
10
|
require "openstax/utilities/exceptions"
|
11
|
+
require "openstax/utilities/active_record_extensions"
|
11
12
|
require "openstax/utilities/settings"
|
12
13
|
require "openstax/utilities/access"
|
13
14
|
require "openstax/utilities/enum"
|
@@ -15,8 +16,11 @@ require "openstax/utilities/ruby"
|
|
15
16
|
require "openstax/utilities/text"
|
16
17
|
require "openstax/utilities/network"
|
17
18
|
require "openstax/utilities/action_list"
|
19
|
+
require "openstax/utilities/acts_as_numberable"
|
20
|
+
require "openstax/utilities/delegate_access_control"
|
18
21
|
|
19
22
|
require "openstax/utilities/classy_helper"
|
23
|
+
require "openstax/utilities/helpers/misc"
|
20
24
|
require "openstax/utilities/helpers/blocks"
|
21
25
|
require "openstax/utilities/helpers/partials"
|
22
26
|
require "openstax/utilities/helpers/action_list"
|
metadata
CHANGED
@@ -1,20 +1,18 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: openstax_utilities
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.
|
5
|
-
prerelease:
|
4
|
+
version: 1.2.0
|
6
5
|
platform: ruby
|
7
6
|
authors:
|
8
7
|
- JP Slavinsky
|
9
8
|
autorequire:
|
10
9
|
bindir: bin
|
11
10
|
cert_chain: []
|
12
|
-
date:
|
11
|
+
date: 2014-02-21 00:00:00.000000000 Z
|
13
12
|
dependencies:
|
14
13
|
- !ruby/object:Gem::Dependency
|
15
14
|
name: rails
|
16
15
|
requirement: !ruby/object:Gem::Requirement
|
17
|
-
none: false
|
18
16
|
requirements:
|
19
17
|
- - ! '>='
|
20
18
|
- !ruby/object:Gem::Version
|
@@ -22,7 +20,6 @@ dependencies:
|
|
22
20
|
type: :runtime
|
23
21
|
prerelease: false
|
24
22
|
version_requirements: !ruby/object:Gem::Requirement
|
25
|
-
none: false
|
26
23
|
requirements:
|
27
24
|
- - ! '>='
|
28
25
|
- !ruby/object:Gem::Version
|
@@ -30,7 +27,6 @@ dependencies:
|
|
30
27
|
- !ruby/object:Gem::Dependency
|
31
28
|
name: attribeautiful
|
32
29
|
requirement: !ruby/object:Gem::Requirement
|
33
|
-
none: false
|
34
30
|
requirements:
|
35
31
|
- - ~>
|
36
32
|
- !ruby/object:Gem::Version
|
@@ -38,7 +34,6 @@ dependencies:
|
|
38
34
|
type: :runtime
|
39
35
|
prerelease: false
|
40
36
|
version_requirements: !ruby/object:Gem::Requirement
|
41
|
-
none: false
|
42
37
|
requirements:
|
43
38
|
- - ~>
|
44
39
|
- !ruby/object:Gem::Version
|
@@ -50,6 +45,9 @@ executables: []
|
|
50
45
|
extensions: []
|
51
46
|
extra_rdoc_files: []
|
52
47
|
files:
|
48
|
+
- MIT-LICENSE
|
49
|
+
- README.md
|
50
|
+
- Rakefile
|
53
51
|
- app/assets/javascripts/openstax_utilities.js
|
54
52
|
- app/assets/stylesheets/openstax_utilities.css
|
55
53
|
- app/helpers/openstax/utilities/osu_helper.rb
|
@@ -60,12 +58,15 @@ files:
|
|
60
58
|
- app/views/osu/shared/_table_row.html.erb
|
61
59
|
- lib/openstax/utilities/access.rb
|
62
60
|
- lib/openstax/utilities/action_list.rb
|
61
|
+
- lib/openstax/utilities/active_record_extensions.rb
|
62
|
+
- lib/openstax/utilities/acts_as_numberable.rb
|
63
63
|
- lib/openstax/utilities/blocks/block_base.rb
|
64
64
|
- lib/openstax/utilities/blocks/section_block.rb
|
65
65
|
- lib/openstax/utilities/blocks/table_block.rb
|
66
66
|
- lib/openstax/utilities/blocks/table_cell_block.rb
|
67
67
|
- lib/openstax/utilities/blocks/table_row_block.rb
|
68
68
|
- lib/openstax/utilities/classy_helper.rb
|
69
|
+
- lib/openstax/utilities/delegate_access_control.rb
|
69
70
|
- lib/openstax/utilities/development.rb
|
70
71
|
- lib/openstax/utilities/engine.rb
|
71
72
|
- lib/openstax/utilities/enum.rb
|
@@ -73,6 +74,7 @@ files:
|
|
73
74
|
- lib/openstax/utilities/helpers/action_list.rb
|
74
75
|
- lib/openstax/utilities/helpers/blocks.rb
|
75
76
|
- lib/openstax/utilities/helpers/datetime.rb
|
77
|
+
- lib/openstax/utilities/helpers/misc.rb
|
76
78
|
- lib/openstax/utilities/helpers/partials.rb
|
77
79
|
- lib/openstax/utilities/network.rb
|
78
80
|
- lib/openstax/utilities/ruby.rb
|
@@ -80,14 +82,14 @@ files:
|
|
80
82
|
- lib/openstax/utilities/text.rb
|
81
83
|
- lib/openstax/utilities/version.rb
|
82
84
|
- lib/openstax_utilities.rb
|
83
|
-
-
|
84
|
-
- Rakefile
|
85
|
-
- README.md
|
85
|
+
- test/dummy/README.rdoc
|
86
|
+
- test/dummy/Rakefile
|
86
87
|
- test/dummy/app/assets/javascripts/application.js
|
87
88
|
- test/dummy/app/assets/stylesheets/application.css
|
88
89
|
- test/dummy/app/controllers/application_controller.rb
|
89
90
|
- test/dummy/app/helpers/application_helper.rb
|
90
91
|
- test/dummy/app/views/layouts/application.html.erb
|
92
|
+
- test/dummy/config.ru
|
91
93
|
- test/dummy/config/application.rb
|
92
94
|
- test/dummy/config/boot.rb
|
93
95
|
- test/dummy/config/database.yml
|
@@ -103,45 +105,35 @@ files:
|
|
103
105
|
- test/dummy/config/initializers/wrap_parameters.rb
|
104
106
|
- test/dummy/config/locales/en.yml
|
105
107
|
- test/dummy/config/routes.rb
|
106
|
-
- test/dummy/config.ru
|
107
108
|
- test/dummy/public/404.html
|
108
109
|
- test/dummy/public/422.html
|
109
110
|
- test/dummy/public/500.html
|
110
111
|
- test/dummy/public/favicon.ico
|
111
|
-
- test/dummy/Rakefile
|
112
|
-
- test/dummy/README.rdoc
|
113
112
|
- test/dummy/script/rails
|
114
113
|
- test/integration/navigation_test.rb
|
115
114
|
homepage: http://github.com/openstax/openstax_utilities
|
116
115
|
licenses:
|
117
116
|
- MIT
|
117
|
+
metadata: {}
|
118
118
|
post_install_message:
|
119
119
|
rdoc_options: []
|
120
120
|
require_paths:
|
121
121
|
- lib
|
122
122
|
required_ruby_version: !ruby/object:Gem::Requirement
|
123
|
-
none: false
|
124
123
|
requirements:
|
125
124
|
- - ! '>='
|
126
125
|
- !ruby/object:Gem::Version
|
127
126
|
version: '0'
|
128
|
-
segments:
|
129
|
-
- 0
|
130
|
-
hash: -1961078437370851561
|
131
127
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
132
|
-
none: false
|
133
128
|
requirements:
|
134
129
|
- - ! '>='
|
135
130
|
- !ruby/object:Gem::Version
|
136
131
|
version: '0'
|
137
|
-
segments:
|
138
|
-
- 0
|
139
|
-
hash: -1961078437370851561
|
140
132
|
requirements: []
|
141
133
|
rubyforge_project:
|
142
|
-
rubygems_version:
|
134
|
+
rubygems_version: 2.2.1
|
143
135
|
signing_key:
|
144
|
-
specification_version:
|
136
|
+
specification_version: 4
|
145
137
|
summary: Utilities for OpenStax web sites
|
146
138
|
test_files:
|
147
139
|
- test/dummy/app/assets/javascripts/application.js
|