lazy_crud 0.9.4 → 0.9.5

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 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: ''