magic_grid 0.9.3.1 → 0.10.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/README.md CHANGED
@@ -1,9 +1,17 @@
1
1
  MagicGrid
2
2
  =========
3
3
 
4
- Takes a collection (ActiveRecord or Array) and creates a paginated table of
5
- it using a supplied column definition. It can generate the rows for you, or
6
- you can supply a block to do it yourself.
4
+ [![Build Status](https://secure.travis-ci.org/rmg/magic_grid.png?branch=master,stable,release)](http://travis-ci.org/rmg/magic_grid)
5
+
6
+ Easy collection display grid with column sorting and pagination.
7
+
8
+ Displays a collection (ActiveRelation or Array) wrapped in an html table with server
9
+ side column sorting, filtering hooks, and search bar. Large collections can be
10
+ paginated with either the will_paginate gem or kaminari gem if you use them, or a naive
11
+ Enumerable based paginator (without pager links) if neither is present.
12
+
13
+ Tables are styled using Themeroller compatible classes, which also don't look _too_ bad
14
+ with Bootstrap.
7
15
 
8
16
  Basic Usage
9
17
  -----------
@@ -18,7 +26,7 @@ In your view:
18
26
 
19
27
  Or a more realistic example:
20
28
 
21
- ```ruby
29
+ ```rhtml
22
30
  <%= magic_grid(@posts, [:title, :author, "Actions"]) do |post| %>
23
31
  <tr>
24
32
  <td><%= link_to(post.title, post) %></td>
data/Rakefile CHANGED
@@ -5,15 +5,19 @@ rescue LoadError
5
5
  puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6
6
  end
7
7
 
8
- require 'yard'
8
+ begin
9
+ require 'yard'
10
+ YARD::Rake::YardocTask.new
11
+ rescue LoadError
12
+ puts "Skipping YARD tasks"
13
+ end
9
14
 
10
- YARD::Rake::YardocTask.new
11
15
 
12
16
  Bundler::GemHelper.install_tasks
13
17
 
14
18
  require 'rake/testtask'
15
19
 
16
- Rake::TestTask.new(:tests) do |t|
20
+ Rake::TestTask.new(:test) do |t|
17
21
  t.libs << 'lib'
18
22
  t.libs << 'test'
19
23
  t.pattern = 'test/**/*_test.rb'
@@ -27,5 +31,7 @@ RSpec::Core::RakeTask.new(:spec) do |t|
27
31
  t.verbose = false
28
32
  end
29
33
 
30
- task :test => [:spec, :tests]
31
- task :default => :test
34
+ desc "Run TestUnit and RSpec tests"
35
+ task :tests => [:spec, :test]
36
+
37
+ task :default => :tests
@@ -1,10 +1,10 @@
1
- require 'will_paginate/view_helpers/action_view'
1
+ #require 'will_paginate/view_helpers/action_view'
2
2
 
3
3
  module MagicGrid
4
4
  class Definition
5
- include WillPaginate::ActionView
5
+ #include WillPaginate::ActionView
6
6
  attr_accessor :columns, :collection, :magic_id, :options, :params,
7
- :current_sort_col, :current_order, :default_order
7
+ :current_sort_col, :current_order, :default_order, :per_page
8
8
 
9
9
  DEFAULTS = {
10
10
  :class => [],
@@ -54,7 +54,8 @@ module MagicGrid
54
54
  raise "I have no idea what that is, but it's not a Hash or an Array"
55
55
  end
56
56
  @default_order = @options[:default_order]
57
- @params = controller.try(:params) || {}
57
+ @params = controller && controller.params || {}
58
+ @per_page = @options[:per_page]
58
59
  @collection = collection
59
60
  begin
60
61
  #if @collection.respond_to? :table
@@ -172,9 +173,24 @@ module MagicGrid
172
173
  @collection = @options[:post_filter].call(@collection)
173
174
  end
174
175
  # Paginate at the very end, after all sorting, filtering, etc..
175
- if @options[:per_page]
176
- @collection = @collection.paginate(:page => param(:page, 1),
177
- :per_page => @options[:per_page])
176
+ if @per_page
177
+ if @collection.respond_to? :paginate
178
+ @collection = @collection.paginate(:page => current_page,
179
+ :per_page => @per_page)
180
+ elsif @collection.respond_to? :page
181
+ @collection = @collection.page(current_page).per(@per_page)
182
+ elsif @collection.is_a?(Array) and Module.const_defined?(:Kaminari)
183
+ @collection = Kaminari.paginate_array(@collection).page(current_page).per(@per_page)
184
+ else
185
+ original = @collection
186
+ @collection = @collection.to_enum.each_slice(@per_page).drop(current_page - 1).first.to_a
187
+ class << @collection
188
+ attr_accessor :current_page, :total_pages, :original_count
189
+ end
190
+ @collection.current_page = current_page
191
+ @collection.original_count = original.count
192
+ @collection.total_pages = original.count / @per_page
193
+ end
178
194
  end
179
195
  end
180
196
 
@@ -190,6 +206,10 @@ module MagicGrid
190
206
  @params.merge :magic_grid_id => @magic_id
191
207
  end
192
208
 
209
+ def current_page
210
+ [param(:page, 1).to_i, 1].max
211
+ end
212
+
193
213
  def order(something)
194
214
  case something
195
215
  when 1, "1", :desc, :DESC, "desc", "DESC"
@@ -1,5 +1,8 @@
1
1
  require 'magic_grid/definition'
2
- require 'will_paginate/array'
2
+
3
+ if Module.const_defined? :WillPaginate
4
+ require 'will_paginate/array'
5
+ end
3
6
 
4
7
  module MagicGrid
5
8
  module Helpers
@@ -62,7 +65,7 @@ module MagicGrid
62
65
  thead << content_tag('tr') do
63
66
  content_tag('td', :class => 'full-width ui-widget-header',
64
67
  :colspan => grid.columns.count) do
65
- pager = will_paginate(grid.collection,
68
+ pager = magic_paginate(grid.collection,
66
69
  :param_name => grid.param_key(:page),
67
70
  :params => base_params
68
71
  )
@@ -96,7 +99,7 @@ module MagicGrid
96
99
  tfoot << content_tag('tr') do
97
100
  content_tag('td', :class => 'full-width ui-widget-header',
98
101
  :colspan => grid.columns.count) do
99
- will_paginate(grid.collection,
102
+ magic_paginate(grid.collection,
100
103
  :param_name => grid.param_key(:page),
101
104
  :params => base_params
102
105
  )
@@ -243,6 +246,21 @@ module MagicGrid
243
246
  searcher
244
247
  end
245
248
 
249
+ def magic_paginate(collection, opts={})
250
+ if respond_to? :will_paginate
251
+ # WillPaginate
252
+ will_paginate collection, opts
253
+ #alias_method :magic_paginate, :will_paginate
254
+ elsif respond_to? :paginate
255
+ #Kaminari, or something else..
256
+ paginate collection, opts
257
+ #alias_method :magic_paginate, :paginate
258
+ else
259
+ ("<!-- page #{collection.current_page} of #{collection.total_pages} -->" +
260
+ '<!-- INSTALL WillPaginate or Kaminari for a pager! -->').html_safe
261
+ end
262
+ end
263
+
246
264
  ::ActionView::Base.send :include, self
247
265
  end
248
266
  end
@@ -1,3 +1,3 @@
1
1
  module MagicGrid
2
- VERSION = "0.9.3.1"
2
+ VERSION = "0.10.0"
3
3
  end
@@ -1,10 +1,31 @@
1
1
  require 'spec_helper'
2
2
  require 'magic_grid/definition'
3
+ require 'active_support/core_ext/hash/indifferent_access'
3
4
 
4
5
  describe MagicGrid::Definition do
5
6
  pending "embarasses me with how tightly it is coupled with.. EVERYTHING"
6
7
 
8
+ shared_examples "a basic grid" do
9
+ its(:options) { should == MagicGrid::Definition.runtime_defaults }
10
+ its(:current_page) { should == 1 }
11
+
12
+ descendings = [1, "1", :desc, :DESC, "desc", "DESC"]
13
+ descendings.each do |down|
14
+ it "should normalize #{down} to 1" do
15
+ expect(subject.order(down)).to eq(1)
16
+ end
17
+ end
18
+
19
+ ascendings = [0, "0", :asc, :ASC, "asc", "ASC"]
20
+ ascendings.each do |up|
21
+ it "should normalize #{up} to 0" do
22
+ expect(subject.order(up)).to eq(0)
23
+ end
24
+ end
25
+ end
26
+
7
27
  let (:empty_collection) { [] }
28
+ let (:large_collection) { 200.times.map { |i| {id: i, name: "Name", description: "Describe me!"} } }
8
29
  let (:column_list) { [:name, :description] }
9
30
  let (:column_hash) { {} }
10
31
 
@@ -24,24 +45,48 @@ describe MagicGrid::Definition do
24
45
  expect { MagicGrid::Definition.new() }.to raise_error
25
46
  end
26
47
 
27
- subject { MagicGrid::Definition.new(column_list, empty_collection) }
28
- its(:base_params) { should include(:magic_grid_id) }
29
- its(:collection) { should == empty_collection }
30
- its(:columns) { should == column_list }
31
- its(:options) { should == MagicGrid::Definition.runtime_defaults }
48
+ context "when given an empty collection" do
49
+ subject { MagicGrid::Definition.new(column_list, empty_collection) }
50
+ its(:base_params) { should include(:magic_grid_id) }
51
+ its(:collection) { should == empty_collection }
52
+ its(:columns) { should == column_list }
53
+ it_behaves_like "a basic grid"
54
+ end
32
55
 
56
+ context "when given a large collection and default options" do
57
+ let(:controller) {
58
+ controller = double()
59
+ controller.stub(:params) { {page: 2} }
60
+ controller
61
+ }
62
+ subject { MagicGrid::Definition.new(column_list, large_collection, controller) }
63
+ it_behaves_like "a basic grid"
64
+ its(:collection) { should_not == empty_collection }
33
65
 
34
- descendings = [1, "1", :desc, :DESC, "desc", "DESC"]
35
- descendings.each do |down|
36
- it "should normalize #{down} to 1" do
37
- expect(subject.order(down)).to eq(1)
38
- end
66
+ its(:collection) { should have(MagicGrid::Definition.runtime_defaults[:per_page]).items }
67
+ its(:columns) { should == column_list }
39
68
  end
40
69
 
41
- ascendings = [0, "0", :asc, :ASC, "asc", "ASC"]
42
- ascendings.each do |up|
43
- it "should normalize #{up} to 0" do
44
- expect(subject.order(up)).to eq(0)
70
+ context "when given a large collection and some options" do
71
+ let(:controller) {
72
+ controller = double()
73
+ controller.stub(:params) { HashWithIndifferentAccess.new({grid_page: 2}) }
74
+ controller
75
+ }
76
+ subject { MagicGrid::Definition.new(column_list, large_collection, controller, id: :grid, per_page: 17) }
77
+ its(:collection) { should_not == empty_collection }
78
+ it "should give a collection with a page worth of items" do
79
+ subject.per_page.should < large_collection.count
80
+ subject.collection.should have(subject.per_page).items
45
81
  end
82
+ its(:columns) { should == column_list }
83
+ its(:current_page) { should == 2 }
84
+
85
+ it "should know how to extract its params" do
86
+ subject.param_key(:page).should == :grid_page
87
+ subject.param_key(:hunkydory).should == :grid_hunkydory
88
+ subject.param(:page).should == 2
89
+ end
90
+
46
91
  end
47
92
  end
data/spec/helpers_spec.rb CHANGED
@@ -10,6 +10,15 @@ describe MagicGrid::Helpers do
10
10
  let(:empty_collection) { [] }
11
11
  let(:column_list) { [:name, :description] }
12
12
 
13
+ let(:view_renderer) {
14
+ double.tap { |v|
15
+ v.stub(:render)
16
+ v.stub(:params) { {} }
17
+ # controller.stub(:option)
18
+ v.stub(:url_for) {|h| "/foo?page=#{h[:page]}"}
19
+ }
20
+ }
21
+
13
22
  describe "#normalize_magic" do
14
23
 
15
24
  it "should turn an array into a MagicGrid::Definition" do
data/spec/spec_helper.rb CHANGED
@@ -1,8 +1,33 @@
1
+ # require 'bundler'
2
+ # Bundler.setup
3
+
4
+ unless ENV['TRAVIS']
5
+ require 'simplecov'
6
+ SimpleCov.start do
7
+ add_filter '/spec/'
8
+ add_filter '/test/'
9
+ end
10
+ end
11
+
1
12
  require 'action_view'
2
13
  require 'rails'
3
- require 'will_paginate'
4
- require 'will_paginate/array'
5
- require 'will_paginate/view_helpers'
14
+
15
+ begin
16
+ require 'will_paginate'
17
+ require 'will_paginate/array'
18
+ require 'will_paginate/view_helpers'
19
+ puts "Testing with WillPaginate"
20
+ rescue LoadError
21
+ puts "skipping WillPaginate"
22
+ end
23
+
24
+ begin
25
+ require 'kaminari'
26
+ require 'kaminari/models/array_extension'
27
+ puts "Testing with Kaminari"
28
+ rescue LoadError
29
+ puts "skipping Kaminari"
30
+ end
6
31
 
7
32
  Rails.backtrace_cleaner.remove_silencers!
8
33
 
@@ -35,7 +60,8 @@ RSpec.configure do |config|
35
60
  config.filter_run :focus
36
61
 
37
62
  config.include ActionView::Helpers
38
- config.include WillPaginate::ViewHelpers
63
+ config.include WillPaginate::ViewHelpers if Module.const_defined? :WillPaginate
64
+ config.include Kaminari::ActionViewExtension if Module.const_defined? :Kaminari
39
65
  config.include ActionFaker
40
66
 
41
67
  # Run specs in random order to surface order dependencies. If you find an
@@ -23,7 +23,8 @@ Dummy::Application.configure do
23
23
  config.action_dispatch.best_standards_support = :builtin
24
24
 
25
25
  # Raise exception on mass assignment protection for Active Record models
26
- config.active_record.mass_assignment_sanitizer = :strict
26
+ # Rails 3.2.x+
27
+ # config.active_record.mass_assignment_sanitizer = :strict
27
28
 
28
29
  # Log the query plan for queries taking more than this (works
29
30
  # with SQLite, MySQL, and PostgreSQL)
@@ -30,7 +30,8 @@ Dummy::Application.configure do
30
30
  config.action_mailer.delivery_method = :test
31
31
 
32
32
  # Raise exception on mass assignment protection for Active Record models
33
- config.active_record.mass_assignment_sanitizer = :strict
33
+ # Rails 3.2.x+
34
+ #config.active_record.mass_assignment_sanitizer = :strict
34
35
 
35
36
  # Print deprecation notices to the stderr
36
37
  config.active_support.deprecation = :stderr
data/test/test_helper.rb CHANGED
@@ -1,6 +1,13 @@
1
1
  # Configure Rails Environment
2
2
  ENV["RAILS_ENV"] = "test"
3
3
 
4
+ unless ENV['TRAVIS']
5
+ require 'simplecov'
6
+ SimpleCov.start do
7
+ add_filter '/dummy/'
8
+ end
9
+ end
10
+
4
11
  require File.expand_path("../dummy/config/environment.rb", __FILE__)
5
12
  require "rails/test_help"
6
13
 
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: magic_grid
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.3.1
4
+ version: 0.10.0
5
5
  prerelease:
6
6
  platform: ruby
7
7
  authors:
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2012-09-12 00:00:00.000000000 Z
12
+ date: 2012-09-17 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: rails
@@ -18,7 +18,7 @@ dependencies:
18
18
  requirements:
19
19
  - - ! '>='
20
20
  - !ruby/object:Gem::Version
21
- version: 3.1.0
21
+ version: '3.1'
22
22
  type: :runtime
23
23
  prerelease: false
24
24
  version_requirements: !ruby/object:Gem::Requirement
@@ -26,23 +26,7 @@ dependencies:
26
26
  requirements:
27
27
  - - ! '>='
28
28
  - !ruby/object:Gem::Version
29
- version: 3.1.0
30
- - !ruby/object:Gem::Dependency
31
- name: will_paginate
32
- requirement: !ruby/object:Gem::Requirement
33
- none: false
34
- requirements:
35
- - - ~>
36
- - !ruby/object:Gem::Version
37
- version: 3.0.0
38
- type: :runtime
39
- prerelease: false
40
- version_requirements: !ruby/object:Gem::Requirement
41
- none: false
42
- requirements:
43
- - - ~>
44
- - !ruby/object:Gem::Version
45
- version: 3.0.0
29
+ version: '3.1'
46
30
  - !ruby/object:Gem::Dependency
47
31
  name: jquery-rails
48
32
  requirement: !ruby/object:Gem::Requirement
@@ -59,103 +43,59 @@ dependencies:
59
43
  - - ! '>='
60
44
  - !ruby/object:Gem::Version
61
45
  version: 1.0.17
62
- - !ruby/object:Gem::Dependency
63
- name: sqlite3
64
- requirement: !ruby/object:Gem::Requirement
65
- none: false
66
- requirements:
67
- - - ! '>='
68
- - !ruby/object:Gem::Version
69
- version: '0'
70
- type: :development
71
- prerelease: false
72
- version_requirements: !ruby/object:Gem::Requirement
73
- none: false
74
- requirements:
75
- - - ! '>='
76
- - !ruby/object:Gem::Version
77
- version: '0'
78
46
  - !ruby/object:Gem::Dependency
79
47
  name: rake
80
48
  requirement: !ruby/object:Gem::Requirement
81
49
  none: false
82
50
  requirements:
83
- - - ! '>='
51
+ - - ~>
84
52
  - !ruby/object:Gem::Version
85
- version: '0'
53
+ version: 0.9.2
86
54
  type: :development
87
55
  prerelease: false
88
56
  version_requirements: !ruby/object:Gem::Requirement
89
57
  none: false
90
58
  requirements:
91
- - - ! '>='
59
+ - - ~>
92
60
  - !ruby/object:Gem::Version
93
- version: '0'
61
+ version: 0.9.2
94
62
  - !ruby/object:Gem::Dependency
95
63
  name: tarantula
96
64
  requirement: !ruby/object:Gem::Requirement
97
65
  none: false
98
66
  requirements:
99
- - - ! '>='
67
+ - - ~>
100
68
  - !ruby/object:Gem::Version
101
- version: '0'
69
+ version: 0.4.0
102
70
  type: :development
103
71
  prerelease: false
104
72
  version_requirements: !ruby/object:Gem::Requirement
105
73
  none: false
106
74
  requirements:
107
- - - ! '>='
75
+ - - ~>
108
76
  - !ruby/object:Gem::Version
109
- version: '0'
77
+ version: 0.4.0
110
78
  - !ruby/object:Gem::Dependency
111
79
  name: rspec
112
80
  requirement: !ruby/object:Gem::Requirement
113
81
  none: false
114
82
  requirements:
115
- - - ! '>='
116
- - !ruby/object:Gem::Version
117
- version: '0'
118
- type: :development
119
- prerelease: false
120
- version_requirements: !ruby/object:Gem::Requirement
121
- none: false
122
- requirements:
123
- - - ! '>='
124
- - !ruby/object:Gem::Version
125
- version: '0'
126
- - !ruby/object:Gem::Dependency
127
- name: yard
128
- requirement: !ruby/object:Gem::Requirement
129
- none: false
130
- requirements:
131
- - - ! '>='
132
- - !ruby/object:Gem::Version
133
- version: '0'
134
- type: :development
135
- prerelease: false
136
- version_requirements: !ruby/object:Gem::Requirement
137
- none: false
138
- requirements:
139
- - - ! '>='
140
- - !ruby/object:Gem::Version
141
- version: '0'
142
- - !ruby/object:Gem::Dependency
143
- name: redcarpet
144
- requirement: !ruby/object:Gem::Requirement
145
- none: false
146
- requirements:
147
- - - ! '>='
83
+ - - ~>
148
84
  - !ruby/object:Gem::Version
149
- version: '0'
85
+ version: 2.11.0
150
86
  type: :development
151
87
  prerelease: false
152
88
  version_requirements: !ruby/object:Gem::Requirement
153
89
  none: false
154
90
  requirements:
155
- - - ! '>='
91
+ - - ~>
156
92
  - !ruby/object:Gem::Version
157
- version: '0'
158
- description: Simple collection displaying with pagination using will_paginate
93
+ version: 2.11.0
94
+ description: ! " Displays a collection (ActiveRelation or Array) wrapped in an
95
+ html table with server\n side column sorting, filtering hooks, and search bar.
96
+ Large collections can be\n paginated with either the will_paginate gem or kaminari
97
+ gem if you use them, or a naive\n Enumerable based paginator (without pager links)
98
+ if neither is present.\n"
159
99
  email:
160
100
  - r.m.graham@gmail.com
161
101
  executables: []
@@ -268,7 +208,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
268
208
  version: '0'
269
209
  segments:
270
210
  - 0
271
- hash: -1296722646557219267
211
+ hash: -4018779425854186674
272
212
  required_rubygems_version: !ruby/object:Gem::Requirement
273
213
  none: false
274
214
  requirements:
@@ -277,13 +217,13 @@ required_rubygems_version: !ruby/object:Gem::Requirement
277
217
  version: '0'
278
218
  segments:
279
219
  - 0
280
- hash: -1296722646557219267
220
+ hash: -4018779425854186674
281
221
  requirements: []
282
222
  rubyforge_project:
283
223
  rubygems_version: 1.8.23
284
224
  signing_key:
285
225
  specification_version: 3
286
- summary: Simple collection displaying with pagination using will_paginate
226
+ summary: Easy collection display grid with column sorting and pagination
287
227
  test_files:
288
228
  - spec/spec_helper.rb
289
229
  - spec/helpers_spec.rb