dynamic_controller 0.0.8 → 0.0.9

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.
Files changed (49) hide show
  1. data/README.md +80 -80
  2. data/dynamic_controller.gemspec +27 -27
  3. data/lib/dynamic_controller/action_controller_extension.rb +18 -16
  4. data/lib/dynamic_controller/class_methods.rb +41 -41
  5. data/lib/dynamic_controller/helper_methods.rb +103 -91
  6. data/lib/dynamic_controller/instance_methods.rb +139 -139
  7. data/lib/dynamic_controller/resource.rb +21 -21
  8. data/lib/dynamic_controller/responder.rb +70 -70
  9. data/lib/dynamic_controller/version.rb +3 -3
  10. data/lib/dynamic_controller.rb +18 -18
  11. data/spec/controller_factory.rb +22 -22
  12. data/spec/controllers/crud_actions_html_spec.rb +111 -111
  13. data/spec/controllers/crud_actions_json_spec.rb +91 -91
  14. data/spec/controllers/nested_crud_actions_html_spec.rb +125 -125
  15. data/spec/controllers/nested_crud_actions_json_spec.rb +97 -97
  16. data/spec/controllers/ransack_spec.rb +57 -57
  17. data/spec/controllers/redefined_responders_html_spec.rb +111 -111
  18. data/spec/controllers/redefined_responders_json_spec.rb +94 -94
  19. data/spec/controllers/two_level_nested_crud_actions_html_spec.rb +133 -133
  20. data/spec/controllers/two_level_nested_crud_actions_json_spec.rb +97 -97
  21. data/spec/custom_responder_format_spec.rb +12 -12
  22. data/spec/dummy/Gemfile +13 -13
  23. data/spec/dummy/app/controllers/cities_controller.rb +95 -95
  24. data/spec/dummy/app/controllers/languages_controller.rb +95 -95
  25. data/spec/dummy/app/controllers/streets_controller.rb +97 -97
  26. data/spec/dummy/app/models/city.rb +6 -6
  27. data/spec/dummy/app/models/language.rb +4 -4
  28. data/spec/dummy/app/models/street.rb +5 -5
  29. data/spec/dummy/app/views/cities/_form.html.erb +25 -25
  30. data/spec/dummy/app/views/cities/index.html.erb +29 -29
  31. data/spec/dummy/app/views/countries/index.html.erb +25 -25
  32. data/spec/dummy/app/views/languages/_form.html.erb +21 -21
  33. data/spec/dummy/app/views/languages/edit.html.erb +6 -6
  34. data/spec/dummy/app/views/languages/index.html.erb +23 -23
  35. data/spec/dummy/app/views/languages/new.html.erb +5 -5
  36. data/spec/dummy/app/views/languages/show.html.erb +10 -10
  37. data/spec/dummy/app/views/streets/_form.html.erb +25 -25
  38. data/spec/dummy/app/views/streets/edit.html.erb +6 -6
  39. data/spec/dummy/app/views/streets/index.html.erb +27 -27
  40. data/spec/dummy/app/views/streets/new.html.erb +5 -5
  41. data/spec/dummy/app/views/streets/show.html.erb +15 -15
  42. data/spec/dummy/config/routes.rb +8 -8
  43. data/spec/dummy/db/migrate/20120922010743_create_languages.rb +9 -9
  44. data/spec/dummy/db/migrate/20120929185302_create_streets.rb +11 -11
  45. data/spec/dummy/db/schema.rb +46 -46
  46. data/spec/factories.rb +21 -21
  47. data/spec/has_crud_actions_options_spec.rb +48 -48
  48. data/spec/spec_helper.rb +35 -35
  49. metadata +58 -17
data/README.md CHANGED
@@ -1,80 +1,80 @@
1
- # DynamicController
2
-
3
- Simple way to add CRUD actions into Rails controllers.
4
-
5
- Suppoted formats HTML and JSON.
6
-
7
- Tested with Ruby 1.9.3 and Rails 3.2.8.
8
-
9
- ## Installation
10
-
11
- Add this line to your application's Gemfile:
12
-
13
- gem 'dynamic_controller'
14
-
15
- And then execute:
16
-
17
- $ bundle
18
-
19
- Or install it yourself as:
20
-
21
- $ gem install dynamic_controller
22
-
23
- ## Adding CRUD actions to resource controller
24
-
25
- class UsersController < ApplicationController
26
- has_crud_actions
27
- end
28
-
29
- has_crud_actions adds index, show, new, edit, create, update and destroy actions to controller
30
-
31
- ## Explicit action specification
32
-
33
- class UsersController < ApplicationController
34
- has_crud_actions only: [:index, :new, :create]
35
- end
36
-
37
- or
38
-
39
- class UsersController < ApplicationController
40
- has_crud_actions except: :destroy
41
- end
42
-
43
-
44
- ## Nested resources support
45
-
46
- class ProfilesController < ApplicationController
47
- has_crud_actions
48
- nested_of User
49
- end
50
-
51
- If has more than one nested level should use
52
-
53
- class StreetsController < ApplicationController
54
- has_crud_actions
55
- nested_of Country
56
- nested_of City
57
- end
58
-
59
- ## Redefining responder
60
-
61
- class LanguagesController < ApplicationController
62
- has_crud_actions
63
-
64
- respond_to_create :html do
65
- redirect_to action: :index
66
- end
67
-
68
- respond_to_update do |format|
69
- format.html { redirect_to action: :index }
70
- format.json { render json: @language }
71
- end
72
- end
73
-
74
- ## Contributing
75
-
76
- 1. Fork it
77
- 2. Create your feature branch (`git checkout -b my-new-feature`)
78
- 3. Commit your changes (`git commit -am 'Added some feature'`)
79
- 4. Push to the branch (`git push origin my-new-feature`)
80
- 5. Create new Pull Request
1
+ # DynamicController
2
+
3
+ Simple way to add CRUD actions into Rails controllers.
4
+
5
+ Suppoted formats HTML and JSON.
6
+
7
+ Tested with Ruby 1.9.3 and Rails 3.2.8.
8
+
9
+ ## Installation
10
+
11
+ Add this line to your application's Gemfile:
12
+
13
+ gem 'dynamic_controller'
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install dynamic_controller
22
+
23
+ ## Adding CRUD actions to resource controller
24
+
25
+ class UsersController < ApplicationController
26
+ has_crud_actions
27
+ end
28
+
29
+ has_crud_actions adds index, show, new, edit, create, update and destroy actions to controller
30
+
31
+ ## Explicit action specification
32
+
33
+ class UsersController < ApplicationController
34
+ has_crud_actions only: [:index, :new, :create]
35
+ end
36
+
37
+ or
38
+
39
+ class UsersController < ApplicationController
40
+ has_crud_actions except: :destroy
41
+ end
42
+
43
+
44
+ ## Nested resources support
45
+
46
+ class ProfilesController < ApplicationController
47
+ has_crud_actions
48
+ nested_of User
49
+ end
50
+
51
+ If has more than one nested level should use
52
+
53
+ class StreetsController < ApplicationController
54
+ has_crud_actions
55
+ nested_of Country
56
+ nested_of City
57
+ end
58
+
59
+ ## Redefining responder
60
+
61
+ class LanguagesController < ApplicationController
62
+ has_crud_actions
63
+
64
+ respond_to_create :html do
65
+ redirect_to action: :index
66
+ end
67
+
68
+ respond_to_update do |format|
69
+ format.html { redirect_to action: :index }
70
+ format.json { render json: @language }
71
+ end
72
+ end
73
+
74
+ ## Contributing
75
+
76
+ 1. Fork it
77
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
78
+ 3. Commit your changes (`git commit -am 'Added some feature'`)
79
+ 4. Push to the branch (`git push origin my-new-feature`)
80
+ 5. Create new Pull Request
@@ -1,27 +1,27 @@
1
- # -*- encoding: utf-8 -*-
2
- $:.push File.expand_path("../lib", __FILE__)
3
- require "dynamic_controller/version"
4
-
5
- Gem::Specification.new do |s|
6
- s.name = 'dynamic_controller'
7
- s.version = DynamicController::VERSION
8
- s.authors = ['Gabriel Naiman']
9
- s.email = ['gabynaiman@gmail.com']
10
- s.homepage = 'https://github.com/gabynaiman/dynamic_controller'
11
- s.summary = 'Simple way to add CRUD actions into Rails controllers'
12
- s.description = 'Simple way to add CRUD actions into Rails controllers'
13
-
14
- s.files = `git ls-files`.split("\n")
15
- s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
- s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
- s.require_paths = ["lib"]
18
-
19
- s.add_dependency 'ransack'
20
- s.add_dependency 'kaminari'
21
- s.add_dependency 'nql', '0.0.4'
22
-
23
- s.add_development_dependency 'rails'
24
- s.add_development_dependency 'sqlite3'
25
- s.add_development_dependency 'rspec-rails'
26
- s.add_development_dependency 'factory_girl_rails'
27
- end
1
+ # -*- encoding: utf-8 -*-
2
+ $:.push File.expand_path("../lib", __FILE__)
3
+ require "dynamic_controller/version"
4
+
5
+ Gem::Specification.new do |s|
6
+ s.name = 'dynamic_controller'
7
+ s.version = DynamicController::VERSION
8
+ s.authors = ['Gabriel Naiman']
9
+ s.email = ['gabynaiman@gmail.com']
10
+ s.homepage = 'https://github.com/gabynaiman/dynamic_controller'
11
+ s.summary = 'Simple way to add CRUD actions into Rails controllers'
12
+ s.description = 'Simple way to add CRUD actions into Rails controllers'
13
+
14
+ s.files = `git ls-files`.split("\n")
15
+ s.test_files = `git ls-files -- {test,spec,features}/*`.split("\n")
16
+ s.executables = `git ls-files -- bin/*`.split("\n").map{ |f| File.basename(f) }
17
+ s.require_paths = ["lib"]
18
+
19
+ s.add_dependency 'ransack'
20
+ s.add_dependency 'kaminari'
21
+ s.add_dependency 'nql', '0.0.4'
22
+
23
+ s.add_development_dependency 'rails'
24
+ s.add_development_dependency 'sqlite3'
25
+ s.add_development_dependency 'rspec-rails'
26
+ s.add_development_dependency 'factory_girl_rails'
27
+ end
@@ -1,17 +1,19 @@
1
- module DynamicController
2
- module ActionControllerExtension
3
-
4
- def has_crud_actions(options={})
5
- @resource_options = Hash[options.map { |k, v| [:only, :except].include?(k.to_sym) ? [k, [v].flatten.map(&:to_sym)] : [k, v] }].reverse_merge(only: DynamicController::ACTIONS, except: [])
6
- send :extend, ClassMethods
7
- send :include, InstanceMethods
8
- send :include, HelperMethods
9
- end
10
-
11
- def nested_of(resource_class)
12
- before_filter :load_parent_models if parent_resources.empty?
13
- parent_resources << Resource.new(resource_class: resource_class)
14
- end
15
-
16
- end
1
+ module DynamicController
2
+ module ActionControllerExtension
3
+
4
+ def has_crud_actions(options={})
5
+ @resource_options = Hash[options.map { |k, v| [:only, :except].include?(k.to_sym) ? [k, [v].flatten.map(&:to_sym)] : [k, v] }].reverse_merge(only: DynamicController::ACTIONS, except: [])
6
+ send :extend, ClassMethods
7
+ send :include, InstanceMethods
8
+ send :include, HelperMethods
9
+
10
+ helper_method :search_query
11
+ end
12
+
13
+ def nested_of(resource_class)
14
+ before_filter :load_parent_models if parent_resources.empty?
15
+ parent_resources << Resource.new(resource_class: resource_class)
16
+ end
17
+
18
+ end
17
19
  end
@@ -1,42 +1,42 @@
1
- module DynamicController
2
- module ClassMethods
3
-
4
- def parent_resources
5
- @parent_resources ||= []
6
- end
7
-
8
- def include_action?(action_name)
9
- (@resource_options[:only] - @resource_options[:except]).include?(action_name)
10
- end
11
-
12
- def redefined_responders
13
- @redefined_responders ||= {}
14
- end
15
-
16
- def redefined_responder_to(action, format=nil)
17
- redefined_responders[redefined_responder_key(action, format)]
18
- end
19
-
20
- def redefined_responder_to?(action, format=nil)
21
- redefined_responders.has_key? redefined_responder_key(action, format)
22
- end
23
-
24
- def responder_formats
25
- @responder_formats ||= [:html, :json]
26
- end
27
-
28
- DynamicController::ACTIONS.each do |action|
29
- define_method "respond_to_#{action}" do |format=nil, &block|
30
- responder_formats << format if format and !responder_formats.include?(format)
31
- redefined_responders[redefined_responder_key(action, format)] = block
32
- end
33
- end
34
-
35
- private
36
-
37
- def redefined_responder_key(action, format=nil)
38
- [action, format].compact.join('_').to_sym
39
- end
40
-
41
- end
1
+ module DynamicController
2
+ module ClassMethods
3
+
4
+ def parent_resources
5
+ @parent_resources ||= []
6
+ end
7
+
8
+ def include_action?(action_name)
9
+ (@resource_options[:only] - @resource_options[:except]).include?(action_name)
10
+ end
11
+
12
+ def redefined_responders
13
+ @redefined_responders ||= {}
14
+ end
15
+
16
+ def redefined_responder_to(action, format=nil)
17
+ redefined_responders[redefined_responder_key(action, format)]
18
+ end
19
+
20
+ def redefined_responder_to?(action, format=nil)
21
+ redefined_responders.has_key? redefined_responder_key(action, format)
22
+ end
23
+
24
+ def responder_formats
25
+ @responder_formats ||= [:html, :json]
26
+ end
27
+
28
+ DynamicController::ACTIONS.each do |action|
29
+ define_method "respond_to_#{action}" do |format=nil, &block|
30
+ responder_formats << format if format and !responder_formats.include?(format)
31
+ redefined_responders[redefined_responder_key(action, format)] = block
32
+ end
33
+ end
34
+
35
+ private
36
+
37
+ def redefined_responder_key(action, format=nil)
38
+ [action, format].compact.join('_').to_sym
39
+ end
40
+
41
+ end
42
42
  end
@@ -1,92 +1,104 @@
1
- module DynamicController
2
- module HelperMethods
3
-
4
- def resource_class
5
- @resource_class ||= (resource_namespace.to_s.split('::') << controller_name.classify).join('::').constantize
6
- end
7
-
8
- def resource_namespace
9
- self.class.to_s.deconstantize.constantize
10
- end
11
-
12
- def collection=(value)
13
- instance_variable_set("@#{controller_name}", value)
14
- end
15
-
16
- def collection
17
- instance_variable_get("@#{controller_name}")
18
- end
19
-
20
- def model=(value)
21
- instance_variable_set("@#{controller_name.singularize}", value)
22
- end
23
-
24
- def model
25
- instance_variable_get("@#{controller_name.singularize}")
26
- end
27
-
28
- def load_parent_models
29
- parent = nil
30
- self.class.parent_resources.each do |resource|
31
- if parent
32
- parent = parent.send(resource.children_name).find(params[resource.param_name])
33
- else
34
- parent = resource.find params[resource.param_name]
35
- end
36
- instance_variable_set resource.instance_variable_name, parent
37
- end
38
- end
39
-
40
- def parent_models
41
- return nil if self.class.parent_resources.empty?
42
- self.class.parent_resources.map do |resource|
43
- instance_variable_get resource.instance_variable_name
44
- end
45
- end
46
-
47
- def parent_model
48
- (parent_models || []).last
49
- end
50
-
51
- def handle_error(error)
52
- respond_to do |format|
53
- format.html { raise error }
54
- format.json { render json: error.message, status: :internal_server_error }
55
- end
56
- end
57
-
58
- def model_extended_attributes
59
- resource_class.column_names | resource_class.reflections.map { |k, v| v.klass.column_names.map { |c| "#{k}_#{c}" } }.flatten
60
- end
61
-
62
- def search_query
63
- params[:q].is_a?(String) ? NQL.to_ransack(params[:q]) : params[:q]
64
- end
65
-
66
- def search_query_valid?
67
- begin
68
- search_node_valid? search_query, model_extended_attributes
69
- rescue NQL::InvalidExpressionError => ex
70
- Rails.logger.debug "Invalid search query: #{params[:q]} | Error: #{ex.message}"
71
- false
72
- end
73
- end
74
-
75
- def search_node_valid?(node, valid_attributes)
76
- return true unless node
77
- node.deep_symbolize_keys.each do |k, v|
78
- if k == :a
79
- return false unless valid_attributes.include?(v['0'.to_sym][:name])
80
- else
81
- if v.is_a?(Hash)
82
- return false unless search_node_valid?(v, valid_attributes)
83
- elsif v.is_a?(Array)
84
- v.select { |e| e.is_a?(Hash) }.each { |e| return false unless search_node_valid?(e, valid_attributes) }
85
- end
86
- end
87
- end
88
- true
89
- end
90
-
91
- end
1
+ module DynamicController
2
+ module HelperMethods
3
+
4
+ def resource_class
5
+ @resource_class ||= (resource_namespace.to_s.split('::') << controller_name.classify).join('::').constantize
6
+ end
7
+
8
+ def resource_namespace
9
+ self.class.to_s.deconstantize.constantize
10
+ end
11
+
12
+ def collection=(value)
13
+ instance_variable_set("@#{controller_name}", value)
14
+ end
15
+
16
+ def collection
17
+ instance_variable_get("@#{controller_name}")
18
+ end
19
+
20
+ def model=(value)
21
+ instance_variable_set("@#{controller_name.singularize}", value)
22
+ end
23
+
24
+ def model
25
+ instance_variable_get("@#{controller_name.singularize}")
26
+ end
27
+
28
+ def load_parent_models
29
+ parent = nil
30
+ self.class.parent_resources.each do |resource|
31
+ if parent
32
+ parent = parent.send(resource.children_name).find(params[resource.param_name])
33
+ else
34
+ parent = resource.find params[resource.param_name]
35
+ end
36
+ instance_variable_set resource.instance_variable_name, parent
37
+ end
38
+ end
39
+
40
+ def parent_models
41
+ return nil if self.class.parent_resources.empty?
42
+ self.class.parent_resources.map do |resource|
43
+ instance_variable_get resource.instance_variable_name
44
+ end
45
+ end
46
+
47
+ def parent_model
48
+ (parent_models || []).last
49
+ end
50
+
51
+ def handle_error(error)
52
+ respond_to do |format|
53
+ format.html { raise error }
54
+ format.json { render json: error.message, status: :internal_server_error }
55
+ end
56
+ end
57
+
58
+ def model_extended_attributes
59
+ resource_class.column_names | resource_class.reflections.map { |k, v| v.klass.column_names.map { |c| "#{k}_#{c}" } }.flatten
60
+ end
61
+
62
+ def search_query
63
+ return @search_query if @search_query
64
+
65
+ query_key = "query_#{params[:controller]}_#{params[:action]}"
66
+
67
+ @search_query = if params.has_key?(:q)
68
+ session[query_key] = params[:q]
69
+ else
70
+ session[query_key]
71
+ end
72
+ end
73
+
74
+ def ransack_query
75
+ search_query.is_a?(String) ? NQL.to_ransack(search_query) : search_query
76
+ end
77
+
78
+ def search_query_valid?
79
+ begin
80
+ search_node_valid? ransack_query, model_extended_attributes
81
+ rescue NQL::InvalidExpressionError => ex
82
+ Rails.logger.debug "Invalid search query: #{params[:q]} | Error: #{ex.message}"
83
+ false
84
+ end
85
+ end
86
+
87
+ def search_node_valid?(node, valid_attributes)
88
+ return true unless node
89
+ node.deep_symbolize_keys.each do |k, v|
90
+ if k == :a
91
+ return false unless valid_attributes.include?(v['0'.to_sym][:name])
92
+ else
93
+ if v.is_a?(Hash)
94
+ return false unless search_node_valid?(v, valid_attributes)
95
+ elsif v.is_a?(Array)
96
+ v.select { |e| e.is_a?(Hash) }.each { |e| return false unless search_node_valid?(e, valid_attributes) }
97
+ end
98
+ end
99
+ end
100
+ true
101
+ end
102
+
103
+ end
92
104
  end