record_collection 0.3.3 → 0.4.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +22 -24
- data/lib/record_collection/base.rb +10 -5
- data/lib/record_collection/rails/routes.rb +4 -4
- data/lib/record_collection/version.rb +1 -1
- data/spec/base/finding_records_spec.rb +29 -0
- data/spec/{validations_spec.rb → base/validations_spec.rb} +0 -0
- data/spec/dummy/app/controllers/employees_controller.rb +6 -8
- data/spec/dummy/app/views/employees/{batch_actions.html.slim → batch_edit.html.slim} +1 -3
- data/spec/dummy/app/views/employees/index.html.slim +1 -1
- metadata +7 -5
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: d5e3294ffdbde01e5cf34236fb973cbf916f4987
|
4
|
+
data.tar.gz: 687dc343a29876feddba4db109df1574284c57b6
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: d56f38fa061aa4639af785b31277e83ea54161edaf04afaced21b874bf91cdb7bb9717daa29b6a4a850516b26e3cf5c95ba424bb3ed2c86536292dc275cf8175
|
7
|
+
data.tar.gz: 888b1a5a779ea182d20677c37481067465bd4aecc2d8811616c4583cebc071555e0f9519867e16707b2900c61589c3cc4bdfb4e4f94694243e8ff27084701608
|
data/README.md
CHANGED
@@ -28,12 +28,12 @@ Or install it yourself as:
|
|
28
28
|
|
29
29
|
## Adding routes
|
30
30
|
Add two collection routes to the normal resources definition.
|
31
|
-
This call behaves exactly as the normal resources :... call,
|
31
|
+
This call behaves exactly as the normal resources :... call,
|
32
32
|
but adds:
|
33
33
|
```ruby
|
34
34
|
collection do
|
35
|
-
get :
|
36
|
-
post :
|
35
|
+
get :batch_edit
|
36
|
+
post :batch_update
|
37
37
|
end
|
38
38
|
```
|
39
39
|
So the route definition in `config/routes.rb` defined as:
|
@@ -44,8 +44,8 @@ is exactly the same as:
|
|
44
44
|
```ruby
|
45
45
|
resources :employees, except: [:new] do
|
46
46
|
collection do
|
47
|
-
get :
|
48
|
-
post :
|
47
|
+
get :batch_edit
|
48
|
+
post :batch_update
|
49
49
|
end
|
50
50
|
end
|
51
51
|
```
|
@@ -58,7 +58,7 @@ resource class. So an employees collection should be defined like:
|
|
58
58
|
class Employee < ActiveRecord::Base
|
59
59
|
# attribute :admin, type: Boolean (defined by database)
|
60
60
|
validates :name, presence: true
|
61
|
-
|
61
|
+
|
62
62
|
end
|
63
63
|
```
|
64
64
|
`app/models/employee/collection.rb`:
|
@@ -80,22 +80,20 @@ the actions in your controller typically looking like:
|
|
80
80
|
```ruby
|
81
81
|
class EmployeesController < ApplicationController
|
82
82
|
# your standard actions here
|
83
|
-
|
84
|
-
# GET /employees/
|
85
|
-
def
|
86
|
-
@
|
87
|
-
@collection
|
88
|
-
redirect_to employees_path, alert: 'No employees selected' if @collection.empty?
|
83
|
+
|
84
|
+
# GET /employees/batch_edit?ids[]=1&ids[]=3&...
|
85
|
+
def batch_edit
|
86
|
+
@collection = Employee::Collection.find(params[:ids])
|
87
|
+
redirect_to employees_path, alert: 'No employees selected' if @collection.empty?
|
89
88
|
end
|
90
89
|
|
91
|
-
# POST /employees/
|
92
|
-
def
|
93
|
-
@
|
94
|
-
@collection
|
95
|
-
if @collection.save
|
90
|
+
# POST /employees/batch_update
|
91
|
+
def batch_update
|
92
|
+
@collection = Employee::Collection.find(params[:ids])
|
93
|
+
if @collection.update params[:collection]
|
96
94
|
redirect_to employees_path, notice: 'Collection is updated'
|
97
95
|
else
|
98
|
-
render '
|
96
|
+
render 'batch_edit'
|
99
97
|
end
|
100
98
|
end
|
101
99
|
end
|
@@ -106,7 +104,7 @@ model types.
|
|
106
104
|
|
107
105
|
## Creating your views
|
108
106
|
The
|
109
|
-
[app/views/employess/
|
107
|
+
[app/views/employess/batch_edit.html.slim](spec/dummy/app/views/employees/batch_edit.html.slim) view is a tricky one.
|
110
108
|
Since we are working on a collection of record, and want to edit those
|
111
109
|
attributes we just want a normal form for editing the attributes,
|
112
110
|
treating the collection as the record itself. The problem however is
|
@@ -125,10 +123,10 @@ the standard [form_helpers](http://guides.rubyonrails.org/form_helpers.html)<br>
|
|
125
123
|
* `optional_text_field`
|
126
124
|
* `optional_input` ([simple_form](https://github.com/plataformatec/simple_form))
|
127
125
|
|
128
|
-
The form you create typically looks like:
|
126
|
+
The form you create typically looks like [app/views/employees/batch_edit.html.slim](spec/dummy/app/views/employees/batch_edit.html.slim):
|
129
127
|
```slim
|
130
128
|
h1 Edit multiple employees
|
131
|
-
= form_for @collection, url: [:
|
129
|
+
= form_for @collection, url: [:batch_update, @collection.record_class] do |f|
|
132
130
|
= f.collection_ids
|
133
131
|
.form-inputs= f.optional_text_field :section
|
134
132
|
.form-inputs= f.optional_boolean :admin
|
@@ -143,13 +141,13 @@ better understanding of how the optional fields work.
|
|
143
141
|
|
144
142
|
## Selecting records from the index using checkboxes (multi_select)
|
145
143
|
The idea behind working with collections is that you end up as a `GET` request at:
|
146
|
-
`+controller+/
|
144
|
+
`+controller+/batch_edit?ids[]=2&ids[]=3` etc. How you achieve this
|
147
145
|
is totally up to yourself, but this gem provides you with a nice
|
148
146
|
standard way of selecting records from the index page. To filter records
|
149
|
-
to a specific subset the [ransack](https://github.com/activerecord-hackery/ransack)
|
147
|
+
to a specific subset the [ransack](https://github.com/activerecord-hackery/ransack)
|
150
148
|
gem also provides a nice way to add filtering to the index page. To add
|
151
149
|
checkbox selecting to your page this gem assumes the following
|
152
|
-
structure using the [Slim lang](http://slim-lang.com/):
|
150
|
+
structure using the [Slim lang](http://slim-lang.com/):
|
153
151
|
```slim
|
154
152
|
table.with-selection
|
155
153
|
thead
|
@@ -4,17 +4,12 @@ module RecordCollection
|
|
4
4
|
include ActiveAttr::Model
|
5
5
|
|
6
6
|
attr_reader :collection
|
7
|
-
protected :collection
|
8
7
|
delegate :first, :last, :size, :length, :count, :empty?, :any?, to: :collection
|
9
8
|
|
10
9
|
class << self
|
11
10
|
def model_name
|
12
11
|
RecordCollection::Name.new(self)
|
13
12
|
end
|
14
|
-
# Find all attributes that are specified with type boolean
|
15
|
-
def boolean_attributes
|
16
|
-
attributes.select{|k,v| v[:type] == ActiveAttr::Typecasting::Boolean}.keys.map(&:to_sym)
|
17
|
-
end
|
18
13
|
|
19
14
|
def human_attribute_name(*args)
|
20
15
|
raise "No record_class defined and could not be inferred based on the inheritance namespace. Please define self.record_clas = ClassNameOfIndividualRecords in the collection" unless record_class.present?
|
@@ -29,6 +24,11 @@ module RecordCollection
|
|
29
24
|
end
|
30
25
|
end
|
31
26
|
|
27
|
+
def find(ids)
|
28
|
+
raise "Cannot call find on a collection object if there is no record_class defined" unless respond_to?(:record_class) && record_class
|
29
|
+
new(ids.present? ? record_class.find(ids) : [])
|
30
|
+
end
|
31
|
+
|
32
32
|
end
|
33
33
|
|
34
34
|
def initialize(collection = [], params = {})
|
@@ -51,6 +51,11 @@ module RecordCollection
|
|
51
51
|
valid? && update_collection_attributes!
|
52
52
|
end
|
53
53
|
|
54
|
+
def update(attributes)
|
55
|
+
self.attributes = attributes
|
56
|
+
save
|
57
|
+
end
|
58
|
+
|
54
59
|
def update_collection_attributes!
|
55
60
|
each { |r| r.update changed_attributes }
|
56
61
|
end
|
@@ -4,14 +4,14 @@ module ActionDispatch::Routing
|
|
4
4
|
# This call behaves exactly as the normal resources :... call,
|
5
5
|
# but adds:
|
6
6
|
# collection do
|
7
|
-
# get :
|
8
|
-
# post :
|
7
|
+
# get :batch_edit
|
8
|
+
# post :batch_update
|
9
9
|
# end
|
10
10
|
def batch_resources(*resources, &blk)
|
11
11
|
batch_blk = Proc.new do
|
12
12
|
collection do
|
13
|
-
get :
|
14
|
-
match :
|
13
|
+
get :batch_edit
|
14
|
+
match :batch_update, via: [:post, :patch, :put]
|
15
15
|
end
|
16
16
|
blk.call if blk
|
17
17
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
|
3
|
+
RSpec.describe Employee::Collection do
|
4
|
+
describe '.find' do
|
5
|
+
describe 'empty argument' do
|
6
|
+
it 'returns an empty collection when initialized with nil' do
|
7
|
+
described_class.find(nil).should be_a described_class
|
8
|
+
described_class.find(nil).should be_empty
|
9
|
+
end
|
10
|
+
it 'returns an empty collection when initialized with empty string' do
|
11
|
+
described_class.find('').should be_a described_class
|
12
|
+
described_class.find('').should be_empty
|
13
|
+
end
|
14
|
+
it 'returns an empty collection when initialized with empty array' do
|
15
|
+
described_class.find([]).should be_a described_class
|
16
|
+
described_class.find([]).should be_empty
|
17
|
+
end
|
18
|
+
end
|
19
|
+
|
20
|
+
describe 'existing records' do
|
21
|
+
it "finds the records" do
|
22
|
+
employee1 = Employee.create name: 'E1', section: 'ABC', admin: true, vegan: false
|
23
|
+
employee2 = Employee.create name: 'E2', section: 'QNP', admin: false, vegan: false
|
24
|
+
described_class.find([employee1.id, employee2.id]).collection.should match_array [employee1, employee2]
|
25
|
+
end
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
end
|
File without changes
|
@@ -45,19 +45,17 @@ class EmployeesController < ApplicationController
|
|
45
45
|
redirect_to employees_url, notice: 'Employee was successfully destroyed.'
|
46
46
|
end
|
47
47
|
|
48
|
-
def
|
49
|
-
@
|
50
|
-
@collection = Employee::Collection.new(@employees)
|
48
|
+
def batch_edit
|
49
|
+
@collection = Employee::Collection.find(params[:ids])
|
51
50
|
redirect_to employees_path, alert: 'No employees selected' if @collection.empty?
|
52
51
|
end
|
53
52
|
|
54
|
-
def
|
55
|
-
@
|
56
|
-
@collection
|
57
|
-
if @collection.save
|
53
|
+
def batch_update
|
54
|
+
@collection = Employee::Collection.find(params[:ids])
|
55
|
+
if @collection.update params[:collection]
|
58
56
|
redirect_to employees_path, notice: 'Collection is updated'
|
59
57
|
else
|
60
|
-
render '
|
58
|
+
render 'batch_edit'
|
61
59
|
end
|
62
60
|
end
|
63
61
|
|
@@ -1,11 +1,9 @@
|
|
1
1
|
h1 Edit multiple employees
|
2
|
-
= form_for @collection, url: [:
|
2
|
+
= form_for @collection, url: [:batch_update, @collection.record_class] do |f|
|
3
3
|
= render 'form_errors', target: @collection
|
4
4
|
.form-inputs= f.optional_text_field :section
|
5
5
|
.form-inputs= f.optional_boolean :admin
|
6
6
|
.form-inputs= f.optional_boolean :vegan
|
7
|
-
/.form-inputs= f.check_box :admin
|
8
|
-
/.form-inputs= f.check_box :vegan
|
9
7
|
.form-actions= f.submit
|
10
8
|
.page-actions
|
11
9
|
= link_to 'Back', employees_path
|
@@ -20,6 +20,6 @@ table.with-selection
|
|
20
20
|
td= link_to 'Edit', edit_employee_path(employee)
|
21
21
|
td= link_to 'Destroy', employee, method: :delete, data: {confirm: 'Are you sure?' }
|
22
22
|
br
|
23
|
-
button.actions-button onclick="window.location = Routes.
|
23
|
+
button.actions-button onclick="window.location = Routes.batch_edit_employees_path({ids: MultiSelect.selected_ids()})" Actions
|
24
24
|
|
25
25
|
= link_to 'New Employee', new_employee_path
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: record_collection
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.4.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Benjamin ter Kuile
|
@@ -321,6 +321,8 @@ files:
|
|
321
321
|
- lib/record_collection/rails/routes.rb
|
322
322
|
- lib/record_collection/version.rb
|
323
323
|
- record_collection.gemspec
|
324
|
+
- spec/base/finding_records_spec.rb
|
325
|
+
- spec/base/validations_spec.rb
|
324
326
|
- spec/dummy/README.rdoc
|
325
327
|
- spec/dummy/Rakefile
|
326
328
|
- spec/dummy/app/assets/images/.keep
|
@@ -341,7 +343,7 @@ files:
|
|
341
343
|
- spec/dummy/app/models/project.rb
|
342
344
|
- spec/dummy/app/views/application/_form_errors.html.slim
|
343
345
|
- spec/dummy/app/views/employees/_form.html.erb
|
344
|
-
- spec/dummy/app/views/employees/
|
346
|
+
- spec/dummy/app/views/employees/batch_edit.html.slim
|
345
347
|
- spec/dummy/app/views/employees/edit.html.erb
|
346
348
|
- spec/dummy/app/views/employees/index.html.slim
|
347
349
|
- spec/dummy/app/views/employees/new.html.erb
|
@@ -386,7 +388,6 @@ files:
|
|
386
388
|
- spec/fixtures/collections.rb
|
387
389
|
- spec/record_selection/base_spec.rb
|
388
390
|
- spec/spec_helper.rb
|
389
|
-
- spec/validations_spec.rb
|
390
391
|
homepage: https://github.com/bterkuile/record_collection
|
391
392
|
licenses:
|
392
393
|
- MIT
|
@@ -412,6 +413,8 @@ signing_key:
|
|
412
413
|
specification_version: 4
|
413
414
|
summary: Manage collections of records in Ruby on Rails
|
414
415
|
test_files:
|
416
|
+
- spec/base/finding_records_spec.rb
|
417
|
+
- spec/base/validations_spec.rb
|
415
418
|
- spec/dummy/README.rdoc
|
416
419
|
- spec/dummy/Rakefile
|
417
420
|
- spec/dummy/app/assets/images/.keep
|
@@ -432,7 +435,7 @@ test_files:
|
|
432
435
|
- spec/dummy/app/models/project.rb
|
433
436
|
- spec/dummy/app/views/application/_form_errors.html.slim
|
434
437
|
- spec/dummy/app/views/employees/_form.html.erb
|
435
|
-
- spec/dummy/app/views/employees/
|
438
|
+
- spec/dummy/app/views/employees/batch_edit.html.slim
|
436
439
|
- spec/dummy/app/views/employees/edit.html.erb
|
437
440
|
- spec/dummy/app/views/employees/index.html.slim
|
438
441
|
- spec/dummy/app/views/employees/new.html.erb
|
@@ -477,5 +480,4 @@ test_files:
|
|
477
480
|
- spec/fixtures/collections.rb
|
478
481
|
- spec/record_selection/base_spec.rb
|
479
482
|
- spec/spec_helper.rb
|
480
|
-
- spec/validations_spec.rb
|
481
483
|
has_rdoc:
|