dynamic_controller 0.0.8 → 0.0.9

Sign up to get free protection for your applications and to get access to all the features.
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