lazy_crud 0.9.4 → 0.9.5

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: fd3014b37d04ad90643b0d6a76b4226ff6744d95
4
- data.tar.gz: 570152da372dbb3901ff85ea3d31f6a50b6e5177
3
+ metadata.gz: 8947aabdd399ff631d4880d675bce69adf90a9cf
4
+ data.tar.gz: f134362d5c4ef9323bffe84aaa63d92cf95c0465
5
5
  SHA512:
6
- metadata.gz: 97e86b3f77c7539212b949b6ce4961f61fa1bc871e3421aa402f8f988b5a0a2feb2fe18134978e18ab164741a81f82133371b80b6e65d753f97d8e33f7d7ddc8
7
- data.tar.gz: abf440e50d917d27016ba78fbe04fe374301c3638ed542cf78a1d408426a77e25e38f5f6597c9f85af074065e69f536f28aee041086d7aba50504c7391b3d340
6
+ metadata.gz: c7e2ed7c6f56685fd07c097bc79c2b34d366715d622aab424560a7ceb6e007da961d1ccd0b815def8cc7d1c908d43ee50e4cabe42de09f384cf963208eb8da73
7
+ data.tar.gz: 0710b4bf1144a3ecda181050e8e8db5da0a1575425d6f1bb4d5eec21b1c779c434ee247c3f4d74a999fd5b8f0f35d3ead811df086d81c0bed16f2eeb7309a8c9
data/Gemfile.lock CHANGED
@@ -1,9 +1,10 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- lazy_crud (0.9.4)
4
+ lazy_crud (0.9.5)
5
5
  activesupport
6
6
  i18n
7
+ responders
7
8
 
8
9
  GEM
9
10
  remote: https://rubygems.org/
@@ -111,6 +112,8 @@ GEM
111
112
  rake (>= 0.8.7)
112
113
  thor (>= 0.18.1, < 2.0)
113
114
  rake (10.4.2)
115
+ responders (2.1.0)
116
+ railties (>= 4.2.0, < 5)
114
117
  rspec (3.2.0)
115
118
  rspec-core (~> 3.2.0)
116
119
  rspec-expectations (~> 3.2.0)
data/README.md CHANGED
@@ -14,12 +14,11 @@ Lazy way to implement common actions in controllers in Rails
14
14
 
15
15
  - Minimal Controller Coding
16
16
  - Resource Can be Scoped to Parent Resource
17
-
18
- ### TODO
19
-
20
- - Generic Error Handeling
21
- - i18n
22
- - lambdas and procs for inserting custom behavior
17
+ - Uses the [responders](https://github.com/plataformatec/responders) gem
18
+ - Enables i18n on flash messages
19
+ - Defaultily enables html and json response types
20
+ - Good for rails apps with an api and / or transitioning to a js framework
21
+ - Responders is a great gem with lots of flexibility. Be sure to check it out.
23
22
 
24
23
  ## Installation
25
24
 
data/lazy_crud.gemspec CHANGED
@@ -24,6 +24,7 @@ Gem::Specification.new do |s|
24
24
  s.required_ruby_version = '>= 2.0'
25
25
 
26
26
  s.add_runtime_dependency "activesupport"
27
+ s.add_runtime_dependency "responders"
27
28
  s.add_runtime_dependency "i18n"
28
29
 
29
30
  # for testing a gem with a rails app (controller specs)
@@ -0,0 +1,23 @@
1
+ module LazyCrud
2
+ module BeforeHookMethods
3
+ include Constants
4
+
5
+ ACTIONS_WITH_HOOKS.each do |action|
6
+ # runs all of the hooks
7
+ define_method("run_before_#{action}_hooks") do
8
+ hook_list = self.send("before_#{action}_hooks")
9
+
10
+ if hook_list
11
+ hook_list.each do |hook|
12
+ hook.call(@resource)
13
+ end
14
+ end
15
+
16
+ # run the before action method if it exists
17
+ if respond_to?("before_#{action}")
18
+ self.send("before_#{action}")
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
@@ -0,0 +1,35 @@
1
+ module LazyCrud
2
+ module ClassMethods
3
+ include Constants
4
+
5
+ # all REST actions will take place on an instance of this class
6
+ def set_resource(klass)
7
+ self.resource_class = klass
8
+ end
9
+
10
+ # for scoping the resource
11
+ # useful for nested routes, such as
12
+ # /event/:event_id/package/:package_id
13
+ # where Event would be the parent class and would scope
14
+ # the package
15
+ def set_resource_parent(klass)
16
+ self.parent_class = klass
17
+ end
18
+
19
+ # the list of parameters to allow through the strong parameter filter
20
+ def set_param_whitelist(*param_list)
21
+ self.param_whitelist = param_list
22
+ end
23
+
24
+ ACTIONS_WITH_HOOKS.each do |action|
25
+ # adds a lambda to the hook array
26
+ define_method("before_#{action}") do |func|
27
+ hook_list = self.send("before_#{action}_hooks")
28
+ hook_list ||= []
29
+ hook_list << func
30
+
31
+ self.send("before_#{action}_hooks=", hook_list)
32
+ end
33
+ end
34
+ end
35
+ end
@@ -0,0 +1,7 @@
1
+ module LazyCrud
2
+ module Constants
3
+
4
+ ACTIONS_WITH_HOOKS = [:create, :update, :destroy]
5
+
6
+ end
7
+ end
@@ -0,0 +1,153 @@
1
+ module LazyCrud
2
+ module InstanceMethods
3
+
4
+ def index
5
+ respond_with(set_collection_instance)
6
+ end
7
+
8
+ def show
9
+ # instance variable set in before_action
10
+ respond_with(get_resource_instance)
11
+ end
12
+
13
+ def new
14
+ set_resource_instance(resource_proxy.new)
15
+ respond_with(get_resource_instance)
16
+ end
17
+
18
+ def edit
19
+ # instance variable set in before_action
20
+ end
21
+
22
+ def create
23
+ @resource = resource_proxy.send(build_method, resource_params)
24
+
25
+ # ensure we can still use model name-based instance variables
26
+ # such as @discount, or @event
27
+ set_resource_instance
28
+
29
+ run_before_create_hooks
30
+
31
+ flash[:notice] = "#{resource_name} has been created." if @resource.save
32
+ respond_with(@resource, location: { action: :index })
33
+ # if @resource.save
34
+ # flash[:notice] = "#{resource_name} has been created."
35
+ # redirect_to action: :index
36
+ # else
37
+ # render action: :new
38
+ # end
39
+ end
40
+
41
+ def update
42
+ run_before_update_hooks
43
+
44
+ @resource.update(resource_params)
45
+ respond_with(@resource, location: { action: :index })
46
+ # if @resource.update(resource_params)
47
+ # redirect_to action: :index
48
+ # else
49
+ # redirect_to action: :edit
50
+ # end
51
+ end
52
+
53
+ def destroy
54
+ run_before_destroy_hooks
55
+ @resource.destroy
56
+
57
+ respond_with(@resource, location: { action: :index })
58
+ # flash[:notice] = "#{resource_name} has been deleted."
59
+ # redirect_to action: :index
60
+ end
61
+
62
+ # only works if deleting of resources occurs by setting
63
+ # the deleted_at field
64
+ def undestroy
65
+ @resource = resource_proxy(true).find(params[:id])
66
+ set_resource_instance
67
+
68
+ @resource.deleted_at = nil
69
+ @resource.save
70
+
71
+ respond_with(@resource, location: { action: :index })
72
+
73
+ # flash[:notice] = "#{resource_name} has been undeleted"
74
+ # redirect_to action: :index
75
+ end
76
+
77
+ private
78
+
79
+ def resource_name
80
+ @resource.try(:name) || @resource.class.name
81
+ end
82
+
83
+ def set_resource
84
+ @resource = resource_proxy.find(params[:id])
85
+ end
86
+
87
+ # use .try() on the params hash, in case the user forgot to provide
88
+ # the attributes
89
+ def resource_params
90
+ params[resource_singular_name].try(:permit, self.class.param_whitelist)
91
+ end
92
+
93
+ # determines if we want to use the parent class if available or
94
+ # if we just use the resource class
95
+ def resource_proxy(with_deleted = false)
96
+ proxy = if parent_instance.present?
97
+ parent_instance.send(resource_plural_name)
98
+ else
99
+ self.class.resource_class
100
+ end
101
+
102
+ if with_deleted and proxy.respond_to?(:with_deleted)
103
+ proxy = proxy.with_deleted
104
+ end
105
+
106
+ proxy
107
+ end
108
+
109
+ # if the resource_proxy has a parent, we can use the
110
+ # build method. Otherwise, resource_proxy, is just the
111
+ # resource's class - in which case we'll use new
112
+ def build_method
113
+ resource_proxy.respond_to?(:build) ? :build : :new
114
+ end
115
+
116
+ # allows all of our views to still use things like
117
+ # @level, @event, @whatever
118
+ # rather than just @resource
119
+ def set_resource_instance(resource = @resource)
120
+ instance_variable_set("@#{resource_singular_name}", resource)
121
+ end
122
+
123
+ def get_resource_instance
124
+ instance_variable_get("@#{resource_singular_name}")
125
+ end
126
+
127
+ # sets the plural instance variable for a collection of objects
128
+ def set_collection_instance
129
+ instance_variable_set("@#{resource_plural_name}", resource_proxy)
130
+ end
131
+
132
+ def parent_instance
133
+ if (not @parent) and self.class.parent_class.present?
134
+ # e.g.: Event => 'event'
135
+ parent_instance_name = self.class.parent_class.name.underscore
136
+ @parent = instance_variable_get("@#{parent_instance_name}")
137
+ end
138
+
139
+ @parent
140
+ end
141
+
142
+ # e.g.: Event => 'events'
143
+ def resource_plural_name
144
+ @association_name ||= self.class.resource_class.name.tableize
145
+ end
146
+
147
+ # e.g.: Event => 'event'
148
+ # alternatively, @resource.class.name.underscore
149
+ def resource_singular_name
150
+ @singular_name ||= resource_plural_name.singularize
151
+ end
152
+ end
153
+ end
@@ -1,3 +1,3 @@
1
1
  module LazyCrud
2
- VERSION = "0.9.4"
2
+ VERSION = "0.9.5"
3
3
  end
data/lib/lazy_crud.rb CHANGED
@@ -1,13 +1,27 @@
1
1
  require 'active_support'
2
2
 
3
3
  require 'lazy_crud/version'
4
+ require 'lazy_crud/constants'
5
+ require 'lazy_crud/before_hook_methods'
6
+ require 'lazy_crud/class_methods'
7
+ require 'lazy_crud/instance_methods'
8
+
9
+ require 'responders'
10
+ require 'responders/json_responder'
4
11
 
5
12
  module LazyCrud
6
13
  extend ActiveSupport::Concern
7
14
 
8
- ACTIONS_WITH_HOOKS = [:create, :update, :destroy]
15
+ include Constants
16
+ include BeforeHookMethods
17
+ include InstanceMethods
9
18
 
10
19
  included do
20
+ # support buth rails view layer, and js framework
21
+ respond_to :html, :json
22
+ # uses custom json responder
23
+ responders :json
24
+
11
25
  class_attribute :resource_class
12
26
  class_attribute :parent_class
13
27
  class_attribute :param_whitelist
@@ -21,189 +35,4 @@ module LazyCrud
21
35
  before_action :set_resource_instance, only: [:show, :edit, :update, :destroy]
22
36
  end
23
37
 
24
- module ClassMethods
25
-
26
- # all REST actions will take place on an instance of this class
27
- def set_resource(klass)
28
- self.resource_class = klass
29
- end
30
-
31
- # for scoping the resource
32
- # useful for nested routes, such as
33
- # /event/:event_id/package/:package_id
34
- # where Event would be the parent class and would scope
35
- # the package
36
- def set_resource_parent(klass)
37
- self.parent_class = klass
38
- end
39
-
40
- # the list of parameters to allow through the strong parameter filter
41
- def set_param_whitelist(*param_list)
42
- self.param_whitelist = param_list
43
- end
44
-
45
- ACTIONS_WITH_HOOKS.each do |action|
46
- # adds a lambda to the hook array
47
- define_method("before_#{action}") do |func|
48
- hook_list = self.send("before_#{action}_hooks")
49
- hook_list ||= []
50
- hook_list << func
51
-
52
- self.send("before_#{action}_hooks=", hook_list)
53
- end
54
- end
55
-
56
- end
57
-
58
- ACTIONS_WITH_HOOKS.each do |action|
59
- # runs all of the hooks
60
- define_method("run_before_#{action}_hooks") do
61
- hook_list = self.send("before_#{action}_hooks")
62
-
63
- if hook_list
64
- hook_list.each do |hook|
65
- hook.call(@resource)
66
- end
67
- end
68
-
69
- # run the before action method if it exists
70
- if respond_to?("before_#{action}")
71
- self.send("before_#{action}")
72
- end
73
- end
74
- end
75
-
76
- def index
77
- set_collection_instance
78
- end
79
-
80
- def show
81
- # instance variable set in before_action
82
- end
83
-
84
- def new
85
- set_resource_instance(resource_proxy.new)
86
- end
87
-
88
- def edit
89
- # instance variable set in before_action
90
- end
91
-
92
- def create
93
- @resource = resource_proxy.send(build_method, resource_params)
94
-
95
- # ensure we can still use model name-based instance variables
96
- set_resource_instance
97
-
98
- run_before_create_hooks
99
- if @resource.save
100
- flash[:notice] = "#{resource_name} has been created."
101
- redirect_to action: :index
102
- else
103
- render action: :new
104
- end
105
- end
106
-
107
- def update
108
- run_before_update_hooks
109
- if @resource.update(resource_params)
110
- redirect_to action: :index
111
- else
112
- redirect_to action: :edit
113
- end
114
- end
115
-
116
- def destroy
117
- run_before_destroy_hooks
118
- @resource.destroy
119
-
120
- flash[:notice] = "#{resource_name} has been deleted."
121
- redirect_to action: :index
122
- end
123
-
124
- # only works if deleting of resources occurs by setting
125
- # the deleted_at field
126
- def undestroy
127
- @resource = resource_proxy(true).find(params[:id])
128
- set_resource_instance
129
-
130
- @resource.deleted_at = nil
131
- @resource.save
132
-
133
- flash[:notice] = "#{resource_name} has been undeleted"
134
- redirect_to action: :index
135
- end
136
-
137
- private
138
-
139
- def resource_name
140
- @resource.try(:name) || @resource.class.name
141
- end
142
-
143
- def set_resource
144
- @resource = resource_proxy.find(params[:id])
145
- end
146
-
147
- # use .try() on the params hash, in case the user forgot to provide
148
- # the attributes
149
- def resource_params
150
- params[resource_singular_name].try(:permit, self.class.param_whitelist)
151
- end
152
-
153
- # determines if we want to use the parent class if available or
154
- # if we just use the resource class
155
- def resource_proxy(with_deleted = false)
156
- proxy = if parent_instance.present?
157
- parent_instance.send(resource_plural_name)
158
- else
159
- self.class.resource_class
160
- end
161
-
162
- if with_deleted and proxy.respond_to?(:with_deleted)
163
- proxy = proxy.with_deleted
164
- end
165
-
166
- proxy
167
- end
168
-
169
- # if the resource_proxy has a parent, we can use the
170
- # build method. Otherwise, resource_proxy, is just the
171
- # resource's class - in which case we'll use new
172
- def build_method
173
- resource_proxy.respond_to?(:build) ? :build : :new
174
- end
175
-
176
- # allows all of our views to still use things like
177
- # @level, @event, @whatever
178
- # rather than just @resource
179
- def set_resource_instance(resource = @resource)
180
- instance_variable_set("@#{resource_singular_name}", resource)
181
- end
182
-
183
- # sets the plural instance variable for a collection of objects
184
- def set_collection_instance
185
- instance_variable_set("@#{resource_plural_name}", resource_proxy)
186
- end
187
-
188
- def parent_instance
189
- if (not @parent) and self.class.parent_class.present?
190
- # e.g.: Event => 'event'
191
- parent_instance_name = self.class.parent_class.name.underscore
192
- @parent = instance_variable_get("@#{parent_instance_name}")
193
- end
194
-
195
- @parent
196
- end
197
-
198
- # e.g.: Event => 'events'
199
- def resource_plural_name
200
- @association_name ||= self.class.resource_class.name.tableize
201
- end
202
-
203
- # e.g.: Event => 'event'
204
- # alternatively, @resource.class.name.underscore
205
- def resource_singular_name
206
- @singular_name ||= resource_plural_name.singularize
207
- end
208
-
209
38
  end
@@ -0,0 +1,16 @@
1
+ # http://stackoverflow.com/questions/9953887
2
+ module Responders::JsonResponder
3
+ protected
4
+
5
+ # simply render the resource even on POST instead of redirecting for ajax
6
+ def api_behavior
7
+ if post?
8
+ display resource, :status => :created
9
+ # render resource instead of 204 no content
10
+ elsif put? || delete?
11
+ display resource, :status => :ok
12
+ else
13
+ super
14
+ end
15
+ end
16
+ end
@@ -9,12 +9,23 @@ describe DiscountsController, type: :controller do
9
9
  end
10
10
 
11
11
  describe '#index' do
12
- it 'sets the collection' do
12
+ before(:each) do
13
13
  create(:discount, event: @event)
14
+ end
15
+
16
+ it 'sets the collection' do
14
17
  get :index, event_id: @event.id
15
18
 
16
19
  expect(assigns(:discounts)).to be_present
17
20
  end
21
+
22
+ it 'returns json' do
23
+ get :index, event_id: @event.id, format: :json
24
+
25
+ expect{
26
+ JSON.parse(response.body)
27
+ }.to_not raise_error
28
+ end
18
29
  end
19
30
 
20
31
  describe '#show' do
@@ -25,6 +36,15 @@ describe DiscountsController, type: :controller do
25
36
 
26
37
  expect(assigns(:discount)).to eq discount
27
38
  end
39
+
40
+ it 'returns json' do
41
+ discount = create(:discount, event: @event)
42
+ get :show, event_id: @event.id, id: discount.id, format: :json
43
+
44
+ expect{
45
+ JSON.parse(response.body)
46
+ }.to_not raise_error
47
+ end
28
48
  end
29
49
 
30
50
  describe '#new' do
@@ -33,11 +53,18 @@ describe DiscountsController, type: :controller do
33
53
 
34
54
  expect(assigns(:discount)).to be_new_record
35
55
  end
56
+
57
+ it 'returns json' do
58
+ get :new, event_id: @event.id, format: :json
59
+
60
+ expect{
61
+ JSON.parse(response.body)
62
+ }.to_not raise_error
63
+ end
36
64
  end
37
65
 
38
66
  describe '#edit' do
39
67
 
40
-
41
68
  it 'sets the instance of the object' do
42
69
  discount = create(:discount, event: @event)
43
70
  get :edit, event_id: @event.id, id: discount.id
@@ -53,6 +80,14 @@ describe DiscountsController, type: :controller do
53
80
 
54
81
  expect(assigns(:discount)).to be_present
55
82
  end
83
+
84
+ it 'returns json' do
85
+ post :create, event_id: @event.id, discount: build(:discount).attributes, format: :json
86
+
87
+ expect{
88
+ JSON.parse(response.body)
89
+ }.to_not raise_error
90
+ end
56
91
  end
57
92
 
58
93
  describe '#update' do
@@ -64,6 +99,16 @@ describe DiscountsController, type: :controller do
64
99
  field = assigns(:discount)
65
100
  expect(field.name).to eq "updated"
66
101
  end
102
+
103
+ it 'returns json' do
104
+ discount = create(:discount, event: @event)
105
+ put :update, event_id: @event.id, id: discount.id,
106
+ discount: { name: "updated" }, format: :json
107
+
108
+ expect{
109
+ JSON.parse(response.body)
110
+ }.to_not raise_error
111
+ end
67
112
  end
68
113
 
69
114
 
@@ -77,6 +122,15 @@ describe DiscountsController, type: :controller do
77
122
 
78
123
  expect(assigns(:discount).deleted_at).to be_present
79
124
  end
125
+
126
+ it 'returns json' do
127
+ discount = create(:discount, event: @event)
128
+ delete :destroy, event_id: @event.id, id: discount.id, format: :json
129
+
130
+ expect{
131
+ JSON.parse(response.body)
132
+ }.to_not raise_error
133
+ end
80
134
  end
81
135
 
82
136
 
@@ -87,9 +141,17 @@ describe DiscountsController, type: :controller do
87
141
  expect{
88
142
  post :undestroy, event_id: @event.id, id: discount.id
89
143
  }.to change(@event.discounts, :count).by 1
90
-
91
144
  expect(assigns(:discount)).to be_present
92
145
  end
146
+
147
+ it 'returns json' do
148
+ discount = create(:discount, event: @event, deleted_at: Time.now)
149
+ post :undestroy, event_id: @event.id, id: discount.id, format: :json
150
+
151
+ expect{
152
+ JSON.parse(response.body)
153
+ }.to_not raise_error
154
+ end
93
155
  end
94
156
 
95
157
 
@@ -5,6 +5,9 @@ require 'rails/all'
5
5
 
6
6
  require 'lazy_crud'
7
7
  require 'paranoia'
8
+ # this would normally be included in the gemfile as
9
+ # a dependency of lazy_crud
10
+ require 'responders'
8
11
 
9
12
  # Require the gems listed in Gemfile, including any gems
10
13
  # you've limited to :test, :development, or :production.
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: lazy_crud
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.4
4
+ version: 0.9.5
5
5
  platform: ruby
6
6
  authors:
7
7
  - L. Preston Sego III
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-05-11 00:00:00.000000000 Z
11
+ date: 2015-05-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -24,6 +24,20 @@ dependencies:
24
24
  - - ">="
25
25
  - !ruby/object:Gem::Version
26
26
  version: '0'
27
+ - !ruby/object:Gem::Dependency
28
+ name: responders
29
+ requirement: !ruby/object:Gem::Requirement
30
+ requirements:
31
+ - - ">="
32
+ - !ruby/object:Gem::Version
33
+ version: '0'
34
+ type: :runtime
35
+ prerelease: false
36
+ version_requirements: !ruby/object:Gem::Requirement
37
+ requirements:
38
+ - - ">="
39
+ - !ruby/object:Gem::Version
40
+ version: '0'
27
41
  - !ruby/object:Gem::Dependency
28
42
  name: i18n
29
43
  requirement: !ruby/object:Gem::Requirement
@@ -192,10 +206,14 @@ files:
192
206
  - LICENSE
193
207
  - README.md
194
208
  - Rakefile
195
- - config/locales/en.yml
196
209
  - lazy_crud.gemspec
197
210
  - lib/lazy_crud.rb
211
+ - lib/lazy_crud/before_hook_methods.rb
212
+ - lib/lazy_crud/class_methods.rb
213
+ - lib/lazy_crud/constants.rb
214
+ - lib/lazy_crud/instance_methods.rb
198
215
  - lib/lazy_crud/version.rb
216
+ - lib/responders/json_responder.rb
199
217
  - spec/integration/discounts_controller_spec.rb
200
218
  - spec/integration/events_controller_spec.rb
201
219
  - spec/integration/users_controller_spec.rb
@@ -298,7 +316,7 @@ rubyforge_project:
298
316
  rubygems_version: 2.4.6
299
317
  signing_key:
300
318
  specification_version: 4
301
- summary: LazyCrud-0.9.4
319
+ summary: LazyCrud-0.9.5
302
320
  test_files:
303
321
  - spec/integration/discounts_controller_spec.rb
304
322
  - spec/integration/events_controller_spec.rb
@@ -1,11 +0,0 @@
1
- en:
2
- lazy_crud:
3
- crud:
4
- success:
5
- create: ''
6
- update: ''
7
- destroy: ''
8
- failure:
9
- create: ''
10
- update: ''
11
- destroy: ''