dynamic_controller 0.0.1 → 0.0.2
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/.gitignore +4 -4
- data/Gemfile +4 -4
- data/README.md +39 -2
- data/Rakefile +1 -1
- data/dynamic_controller.gemspec +26 -26
- data/lib/dynamic_controller/class_methods.rb +48 -0
- data/lib/dynamic_controller/helper_methods.rb +59 -0
- data/lib/dynamic_controller/instance_methods.rb +127 -0
- data/lib/dynamic_controller/resource.rb +21 -0
- data/lib/dynamic_controller/responder.rb +71 -0
- data/lib/dynamic_controller/version.rb +3 -3
- data/lib/dynamic_controller.rb +12 -180
- data/spec/controller_factory.rb +15 -0
- data/spec/controllers/crud_actions_json_spec.rb +3 -3
- data/spec/controllers/nested_crud_actions_html_spec.rb +9 -8
- data/spec/controllers/nested_crud_actions_json_spec.rb +11 -11
- data/spec/controllers/redefined_responders_html_spec.rb +112 -0
- data/spec/controllers/redefined_responders_json_spec.rb +95 -0
- data/spec/controllers/two_level_nested_crud_actions_html_spec.rb +134 -0
- data/spec/controllers/two_level_nested_crud_actions_json_spec.rb +98 -0
- data/spec/dummy/.gitignore +15 -15
- data/spec/dummy/Gemfile +12 -12
- data/spec/dummy/README.rdoc +261 -261
- data/spec/dummy/Rakefile +7 -7
- data/spec/dummy/app/assets/javascripts/application.js +15 -15
- data/spec/dummy/app/assets/stylesheets/application.css +13 -13
- data/spec/dummy/app/assets/stylesheets/scaffolds.css.scss +69 -69
- data/spec/dummy/app/controllers/application_controller.rb +3 -3
- data/spec/dummy/app/controllers/cities_controller.rb +95 -94
- data/spec/dummy/app/controllers/countries_controller.rb +86 -86
- data/spec/dummy/app/controllers/languages_controller.rb +95 -0
- data/spec/dummy/app/controllers/streets_controller.rb +97 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -2
- data/spec/dummy/app/models/city.rb +6 -5
- data/spec/dummy/app/models/country.rb +5 -5
- data/spec/dummy/app/models/language.rb +4 -0
- data/spec/dummy/app/models/street.rb +5 -0
- data/spec/dummy/app/views/cities/_form.html.erb +25 -25
- data/spec/dummy/app/views/cities/edit.html.erb +6 -6
- data/spec/dummy/app/views/cities/index.html.erb +29 -25
- data/spec/dummy/app/views/cities/new.html.erb +5 -5
- data/spec/dummy/app/views/cities/show.html.erb +15 -15
- data/spec/dummy/app/views/countries/_form.html.erb +21 -21
- data/spec/dummy/app/views/countries/edit.html.erb +6 -6
- data/spec/dummy/app/views/countries/index.html.erb +25 -23
- data/spec/dummy/app/views/countries/new.html.erb +5 -5
- data/spec/dummy/app/views/countries/show.html.erb +10 -10
- data/spec/dummy/app/views/languages/_form.html.erb +21 -0
- data/spec/dummy/app/views/languages/edit.html.erb +6 -0
- data/spec/dummy/app/views/languages/index.html.erb +23 -0
- data/spec/dummy/app/views/languages/new.html.erb +5 -0
- data/spec/dummy/app/views/languages/show.html.erb +10 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -14
- data/spec/dummy/app/views/streets/_form.html.erb +25 -0
- data/spec/dummy/app/views/streets/edit.html.erb +6 -0
- data/spec/dummy/app/views/streets/index.html.erb +27 -0
- data/spec/dummy/app/views/streets/new.html.erb +5 -0
- data/spec/dummy/app/views/streets/show.html.erb +15 -0
- data/spec/dummy/config/application.rb +62 -62
- data/spec/dummy/config/boot.rb +6 -6
- data/spec/dummy/config/database.yml +25 -25
- data/spec/dummy/config/environment.rb +5 -5
- data/spec/dummy/config/environments/development.rb +37 -37
- data/spec/dummy/config/environments/production.rb +67 -67
- data/spec/dummy/config/environments/test.rb +37 -37
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -7
- data/spec/dummy/config/initializers/inflections.rb +15 -15
- data/spec/dummy/config/initializers/mime_types.rb +5 -5
- data/spec/dummy/config/initializers/secret_token.rb +7 -7
- data/spec/dummy/config/initializers/session_store.rb +8 -8
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -14
- data/spec/dummy/config/locales/en.yml +5 -5
- data/spec/dummy/config/routes.rb +8 -5
- data/spec/dummy/config.ru +4 -4
- data/spec/dummy/db/migrate/20120907174827_create_countries.rb +9 -9
- data/spec/dummy/db/migrate/20120907230842_create_cities.rb +11 -11
- data/spec/dummy/db/migrate/20120922010743_create_languages.rb +9 -0
- data/spec/dummy/db/migrate/20120929185302_create_streets.rb +11 -0
- data/spec/dummy/db/schema.rb +16 -1
- data/spec/dummy/db/seeds.rb +7 -7
- data/spec/dummy/doc/README_FOR_APP +2 -2
- data/spec/dummy/public/404.html +26 -26
- data/spec/dummy/public/422.html +26 -26
- data/spec/dummy/public/500.html +25 -25
- data/spec/dummy/public/index.html +241 -241
- data/spec/dummy/public/robots.txt +5 -5
- data/spec/dummy/script/rails +6 -6
- data/spec/factories.rb +9 -0
- data/spec/has_crud_actions_options_spec.rb +49 -0
- data/spec/spec_helper.rb +1 -0
- metadata +43 -16
data/.gitignore
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
*.gem
|
|
2
|
-
.bundle
|
|
3
|
-
Gemfile.lock
|
|
4
|
-
pkg/*
|
|
1
|
+
*.gem
|
|
2
|
+
.bundle
|
|
3
|
+
Gemfile.lock
|
|
4
|
+
pkg/*
|
|
5
5
|
.idea
|
data/Gemfile
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
source "http://rubygems.org"
|
|
2
|
-
|
|
3
|
-
# Specify your gem's dependencies in dynamic_controller.gemspec
|
|
4
|
-
gemspec
|
|
1
|
+
source "http://rubygems.org"
|
|
2
|
+
|
|
3
|
+
# Specify your gem's dependencies in dynamic_controller.gemspec
|
|
4
|
+
gemspec
|
data/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# DynamicController
|
|
2
2
|
|
|
3
|
-
Simple way to add CRUD actions
|
|
3
|
+
Simple way to add CRUD actions into Rails controllers.
|
|
4
4
|
|
|
5
5
|
Suppoted formats HTML and JSON.
|
|
6
6
|
|
|
@@ -28,10 +28,47 @@ Or install it yourself as:
|
|
|
28
28
|
|
|
29
29
|
has_crud_actions adds index, show, new, edit, create, update and destroy actions to controller
|
|
30
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
|
+
|
|
31
44
|
## Nested resources support
|
|
32
45
|
|
|
33
46
|
class ProfilesController < ApplicationController
|
|
34
|
-
has_crud_actions
|
|
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
|
|
35
72
|
end
|
|
36
73
|
|
|
37
74
|
## Contributing
|
data/Rakefile
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
require "bundler/gem_tasks"
|
|
1
|
+
require "bundler/gem_tasks"
|
data/dynamic_controller.gemspec
CHANGED
|
@@ -1,26 +1,26 @@
|
|
|
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
|
|
12
|
-
s.description = 'Simple way to add CRUD actions
|
|
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
|
-
|
|
22
|
-
s.add_development_dependency 'rails'
|
|
23
|
-
s.add_development_dependency 'sqlite3'
|
|
24
|
-
s.add_development_dependency 'rspec-rails'
|
|
25
|
-
s.add_development_dependency 'factory_girl_rails'
|
|
26
|
-
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
|
+
|
|
22
|
+
s.add_development_dependency 'rails'
|
|
23
|
+
s.add_development_dependency 'sqlite3'
|
|
24
|
+
s.add_development_dependency 'rspec-rails'
|
|
25
|
+
s.add_development_dependency 'factory_girl_rails'
|
|
26
|
+
end
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
module DynamicController
|
|
2
|
+
module ClassMethods
|
|
3
|
+
ACTIONS = [:index, :show, :new, :create, :edit, :update, :destroy]
|
|
4
|
+
|
|
5
|
+
def has_crud_actions(options={})
|
|
6
|
+
@resource_options = Hash[options.map { |k, v| [:only, :except].include?(k.to_sym) ? [k, [v].flatten.map(&:to_sym)] : [k, v] }].reverse_merge(only: ACTIONS, except: [])
|
|
7
|
+
send :include, InstanceMethods
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def nested_of(resource_class)
|
|
11
|
+
before_filter :load_parent_models if parent_resources.empty?
|
|
12
|
+
self.parent_resources << Resource.new(resource_class: resource_class)
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
def parent_resources
|
|
16
|
+
@parent_resources ||= []
|
|
17
|
+
end
|
|
18
|
+
|
|
19
|
+
def include_action?(action_name)
|
|
20
|
+
(@resource_options[:only] - @resource_options[:except]).include?(action_name)
|
|
21
|
+
end
|
|
22
|
+
|
|
23
|
+
def redefined_responders
|
|
24
|
+
@redefined_responders ||= {}
|
|
25
|
+
end
|
|
26
|
+
|
|
27
|
+
def redefined_responder_to(action, format=nil)
|
|
28
|
+
redefined_responders[redefined_responder_key(action, format)]
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
def redefined_responder_to?(action, format=nil)
|
|
32
|
+
redefined_responders.has_key? redefined_responder_key(action, format)
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
ACTIONS.each do |action|
|
|
36
|
+
define_method "respond_to_#{action}" do |format=nil, &block|
|
|
37
|
+
redefined_responders[redefined_responder_key(action, format)] = block
|
|
38
|
+
end
|
|
39
|
+
end
|
|
40
|
+
|
|
41
|
+
private
|
|
42
|
+
|
|
43
|
+
def redefined_responder_key(action, format=nil)
|
|
44
|
+
[action, format].compact.join('_').to_sym
|
|
45
|
+
end
|
|
46
|
+
|
|
47
|
+
end
|
|
48
|
+
end
|
|
@@ -0,0 +1,59 @@
|
|
|
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
|
+
end
|
|
59
|
+
end
|
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
module DynamicController
|
|
2
|
+
module InstanceMethods
|
|
3
|
+
|
|
4
|
+
def self.included(base)
|
|
5
|
+
base.send :include, HelperMethods
|
|
6
|
+
base.rescue_from StandardError, with: :handle_error
|
|
7
|
+
|
|
8
|
+
if base.include_action?(:index)
|
|
9
|
+
base.send :define_method, :index do
|
|
10
|
+
if parent_model
|
|
11
|
+
self.collection = parent_model.send(controller_name).search(params[:q]).result.page(params[:page])
|
|
12
|
+
else
|
|
13
|
+
self.collection = resource_class.search(params[:q]).result.page(params[:page])
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
Responder.new(self).index
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
if base.include_action?(:show)
|
|
21
|
+
base.send :define_method, :show do
|
|
22
|
+
if parent_model
|
|
23
|
+
self.model = parent_model.send(controller_name).find(params[:id])
|
|
24
|
+
else
|
|
25
|
+
self.model = resource_class.find(params[:id])
|
|
26
|
+
end
|
|
27
|
+
|
|
28
|
+
Responder.new(self).show
|
|
29
|
+
end
|
|
30
|
+
end
|
|
31
|
+
|
|
32
|
+
if base.include_action?(:new)
|
|
33
|
+
base.send :define_method, :new do
|
|
34
|
+
if parent_model
|
|
35
|
+
self.model = parent_model.send(controller_name).build
|
|
36
|
+
else
|
|
37
|
+
self.model = resource_class.new
|
|
38
|
+
end
|
|
39
|
+
|
|
40
|
+
Responder.new(self).new
|
|
41
|
+
end
|
|
42
|
+
end
|
|
43
|
+
|
|
44
|
+
if base.include_action?(:edit)
|
|
45
|
+
base.send :define_method, :edit do
|
|
46
|
+
if parent_model
|
|
47
|
+
self.model = parent_model.send(controller_name).find(params[:id])
|
|
48
|
+
else
|
|
49
|
+
self.model = resource_class.find(params[:id])
|
|
50
|
+
end
|
|
51
|
+
|
|
52
|
+
Responder.new(self).edit
|
|
53
|
+
end
|
|
54
|
+
end
|
|
55
|
+
|
|
56
|
+
if base.include_action?(:create)
|
|
57
|
+
base.send :define_method, :create do
|
|
58
|
+
if parent_model
|
|
59
|
+
self.model = parent_model.send(controller_name).build(params[controller_name.singularize])
|
|
60
|
+
else
|
|
61
|
+
self.model = resource_class.new(params[controller_name.singularize])
|
|
62
|
+
end
|
|
63
|
+
|
|
64
|
+
if model.save
|
|
65
|
+
flash_message = "#{resource_class.model_name.human} successfully created"
|
|
66
|
+
if params[:save_and_new]
|
|
67
|
+
flash[:success] = flash_message
|
|
68
|
+
redirect_to action: :new
|
|
69
|
+
else
|
|
70
|
+
flash.now[:success] = flash_message
|
|
71
|
+
Responder.new(self).create
|
|
72
|
+
end
|
|
73
|
+
else
|
|
74
|
+
respond_to do |format|
|
|
75
|
+
format.html { render :new }
|
|
76
|
+
format.json { render json: model.errors, status: :unprocessable_entity }
|
|
77
|
+
end
|
|
78
|
+
end
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
|
|
82
|
+
if base.include_action?(:update)
|
|
83
|
+
base.send :define_method, :update do
|
|
84
|
+
if parent_model
|
|
85
|
+
self.model = parent_model.send(controller_name).find(params[:id])
|
|
86
|
+
else
|
|
87
|
+
self.model = resource_class.find(params[:id])
|
|
88
|
+
end
|
|
89
|
+
|
|
90
|
+
if model.update_attributes(params[controller_name.singularize])
|
|
91
|
+
flash.now[:success] = "#{resource_class.model_name.human} successfully updated"
|
|
92
|
+
Responder.new(self).update
|
|
93
|
+
else
|
|
94
|
+
respond_to do |format|
|
|
95
|
+
format.html { render :edit }
|
|
96
|
+
format.json { render json: model.errors, status: :unprocessable_entity }
|
|
97
|
+
end
|
|
98
|
+
end
|
|
99
|
+
end
|
|
100
|
+
|
|
101
|
+
end
|
|
102
|
+
|
|
103
|
+
if base.include_action?(:destroy)
|
|
104
|
+
base.send :define_method, :destroy do
|
|
105
|
+
if parent_model
|
|
106
|
+
self.model = parent_model.send(controller_name).find(params[:id])
|
|
107
|
+
else
|
|
108
|
+
self.model = resource_class.find(params[:id])
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
if model.destroy
|
|
112
|
+
flash[:warning] = "#{resource_class.model_name.human} successfully removed"
|
|
113
|
+
Responder.new(self).destroy
|
|
114
|
+
else
|
|
115
|
+
flash[:danger] = "#{resource_class.model_name.human} could not be deleted"
|
|
116
|
+
respond_to do |format|
|
|
117
|
+
format.html { redirect_to action: :index }
|
|
118
|
+
format.json { render json: model.errors, status: :unprocessable_entity }
|
|
119
|
+
end
|
|
120
|
+
end
|
|
121
|
+
end
|
|
122
|
+
end
|
|
123
|
+
|
|
124
|
+
end
|
|
125
|
+
|
|
126
|
+
end
|
|
127
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
module DynamicController
|
|
2
|
+
class Resource
|
|
3
|
+
attr_reader :resource_class,
|
|
4
|
+
:param_name,
|
|
5
|
+
:instance_variable_name,
|
|
6
|
+
:children_name
|
|
7
|
+
|
|
8
|
+
def initialize(options={})
|
|
9
|
+
raise 'Param resource_class must be a class' if !options.has_key?(:resource_class) || !options[:resource_class].is_a?(Class)
|
|
10
|
+
@resource_class = options[:resource_class]
|
|
11
|
+
@param_name = options[:param_name] || "#{resource_class.to_s.demodulize.underscore}_id"
|
|
12
|
+
@instance_variable_name = options[:instance_variable_name] || "@#{resource_class.to_s.demodulize.underscore}"
|
|
13
|
+
@children_name = options[:children_name] || resource_class.to_s.demodulize.pluralize.underscore
|
|
14
|
+
end
|
|
15
|
+
|
|
16
|
+
def find(id)
|
|
17
|
+
resource_class.find(id)
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,71 @@
|
|
|
1
|
+
module DynamicController
|
|
2
|
+
class Responder
|
|
3
|
+
|
|
4
|
+
def initialize(controller)
|
|
5
|
+
@controller = controller
|
|
6
|
+
end
|
|
7
|
+
|
|
8
|
+
def index
|
|
9
|
+
action :index,
|
|
10
|
+
html: Proc.new {},
|
|
11
|
+
json: Proc.new { render json: collection }
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def show
|
|
15
|
+
action :show,
|
|
16
|
+
html: Proc.new {},
|
|
17
|
+
json: Proc.new { render json: model }
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
def new
|
|
21
|
+
action :new,
|
|
22
|
+
html: Proc.new {}
|
|
23
|
+
end
|
|
24
|
+
|
|
25
|
+
def edit
|
|
26
|
+
action :edit,
|
|
27
|
+
html: Proc.new {}
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def create
|
|
31
|
+
action :create,
|
|
32
|
+
html: Proc.new { redirect_to action: :show, id: model.id },
|
|
33
|
+
json: Proc.new { render json: model, status: :created }
|
|
34
|
+
end
|
|
35
|
+
|
|
36
|
+
def update
|
|
37
|
+
action :update,
|
|
38
|
+
html: Proc.new { redirect_to action: :show, id: model.id },
|
|
39
|
+
json: Proc.new { head :no_content }
|
|
40
|
+
end
|
|
41
|
+
|
|
42
|
+
def destroy
|
|
43
|
+
action :destroy,
|
|
44
|
+
html: Proc.new { redirect_to action: :index },
|
|
45
|
+
json: Proc.new { head :no_content }
|
|
46
|
+
end
|
|
47
|
+
|
|
48
|
+
private
|
|
49
|
+
|
|
50
|
+
def action(name, blocks={})
|
|
51
|
+
@controller.instance_eval do
|
|
52
|
+
if self.class.redefined_responder_to?(name)
|
|
53
|
+
respond_to do |format|
|
|
54
|
+
self.instance_exec format, &self.class.redefined_responder_to(name)
|
|
55
|
+
end
|
|
56
|
+
else
|
|
57
|
+
respond_to do |format|
|
|
58
|
+
[:html, :json].each do |mime|
|
|
59
|
+
if self.class.redefined_responder_to?(name, mime)
|
|
60
|
+
format.send(mime) { self.instance_eval &self.class.redefined_responder_to(name, mime) }
|
|
61
|
+
elsif blocks[mime]
|
|
62
|
+
format.send(mime) { self.instance_eval &blocks[mime] }
|
|
63
|
+
end
|
|
64
|
+
end
|
|
65
|
+
end
|
|
66
|
+
end
|
|
67
|
+
end
|
|
68
|
+
end
|
|
69
|
+
|
|
70
|
+
end
|
|
71
|
+
end
|
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
module DynamicController
|
|
2
|
-
VERSION = "0.0.
|
|
3
|
-
end
|
|
1
|
+
module DynamicController
|
|
2
|
+
VERSION = "0.0.2"
|
|
3
|
+
end
|
data/lib/dynamic_controller.rb
CHANGED
|
@@ -1,180 +1,12 @@
|
|
|
1
|
-
require '
|
|
2
|
-
require '
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
before_filter :load_nested if options[:nested_of]
|
|
14
|
-
@dynamic_options = options
|
|
15
|
-
end
|
|
16
|
-
|
|
17
|
-
end
|
|
18
|
-
|
|
19
|
-
module CrudActions
|
|
20
|
-
|
|
21
|
-
def self.included(base)
|
|
22
|
-
base.helper_method [:resource_class, :controller_namespace]
|
|
23
|
-
base.respond_to :html, :json
|
|
24
|
-
base.rescue_from StandardError, with: :handle_error
|
|
25
|
-
end
|
|
26
|
-
|
|
27
|
-
def index
|
|
28
|
-
if parent_model
|
|
29
|
-
self.collection = parent_model.send(controller_name).search(params[:q]).result.page(params[:page])
|
|
30
|
-
else
|
|
31
|
-
self.collection = resource_class.search(params[:q]).result.page(params[:page])
|
|
32
|
-
end
|
|
33
|
-
|
|
34
|
-
respond_with collection
|
|
35
|
-
end
|
|
36
|
-
|
|
37
|
-
def show
|
|
38
|
-
if parent_model
|
|
39
|
-
self.model = parent_model.send(controller_name).find(params[:id])
|
|
40
|
-
else
|
|
41
|
-
self.model = resource_class.find(params[:id])
|
|
42
|
-
end
|
|
43
|
-
|
|
44
|
-
respond_with model
|
|
45
|
-
end
|
|
46
|
-
|
|
47
|
-
def new
|
|
48
|
-
if parent_model
|
|
49
|
-
self.model = parent_model.send(controller_name).build
|
|
50
|
-
else
|
|
51
|
-
self.model = resource_class.new
|
|
52
|
-
end
|
|
53
|
-
end
|
|
54
|
-
|
|
55
|
-
def edit
|
|
56
|
-
if parent_model
|
|
57
|
-
self.model = parent_model.send(controller_name).find(params[:id])
|
|
58
|
-
else
|
|
59
|
-
self.model = resource_class.find(params[:id])
|
|
60
|
-
end
|
|
61
|
-
end
|
|
62
|
-
|
|
63
|
-
def create
|
|
64
|
-
if parent_model
|
|
65
|
-
self.model = parent_model.send(controller_name).build(params[resource_class.model_name.underscore])
|
|
66
|
-
else
|
|
67
|
-
self.model = resource_class.new(params[resource_class.model_name.underscore])
|
|
68
|
-
end
|
|
69
|
-
|
|
70
|
-
if model.save
|
|
71
|
-
flash_message = "#{resource_class.model_name.human} successfully created"
|
|
72
|
-
if params[:save_and_new]
|
|
73
|
-
flash[:success] = flash_message
|
|
74
|
-
redirect_to action: :new
|
|
75
|
-
else
|
|
76
|
-
flash.now[:success] = flash_message
|
|
77
|
-
respond_to do |format|
|
|
78
|
-
format.html { redirect_to url_for([parent_model, model].compact) }
|
|
79
|
-
format.json { render json: model, status: :created }
|
|
80
|
-
end
|
|
81
|
-
end
|
|
82
|
-
else
|
|
83
|
-
respond_to do |format|
|
|
84
|
-
format.html { render :new }
|
|
85
|
-
format.json { render json: model.errors, status: :unprocessable_entity }
|
|
86
|
-
end
|
|
87
|
-
end
|
|
88
|
-
end
|
|
89
|
-
|
|
90
|
-
def update
|
|
91
|
-
if parent_model
|
|
92
|
-
self.model = parent_model.send(controller_name).find(params[:id])
|
|
93
|
-
else
|
|
94
|
-
self.model = resource_class.find(params[:id])
|
|
95
|
-
end
|
|
96
|
-
|
|
97
|
-
if model.update_attributes(params[resource_class.model_name.underscore])
|
|
98
|
-
flash.now[:success] = "#{resource_class.model_name.human} successfully updated"
|
|
99
|
-
respond_to do |format|
|
|
100
|
-
format.html { redirect_to url_for([parent_model, model].compact) }
|
|
101
|
-
format.json { head :no_content }
|
|
102
|
-
end
|
|
103
|
-
else
|
|
104
|
-
respond_to do |format|
|
|
105
|
-
format.html { render :edit }
|
|
106
|
-
format.json { render json: model.errors, status: :unprocessable_entity }
|
|
107
|
-
end
|
|
108
|
-
end
|
|
109
|
-
end
|
|
110
|
-
|
|
111
|
-
def destroy
|
|
112
|
-
if parent_model
|
|
113
|
-
self.model = parent_model.send(controller_name).find(params[:id])
|
|
114
|
-
else
|
|
115
|
-
self.model = resource_class.find(params[:id])
|
|
116
|
-
end
|
|
117
|
-
|
|
118
|
-
if model.destroy
|
|
119
|
-
flash[:warning] = "#{resource_class.model_name.human} successfully removed"
|
|
120
|
-
respond_to do |format|
|
|
121
|
-
format.html { redirect_to action: :index }
|
|
122
|
-
format.json { head :no_content }
|
|
123
|
-
end
|
|
124
|
-
else
|
|
125
|
-
flash[:danger] = "#{resource_class.model_name.human} could not be deleted"
|
|
126
|
-
respond_to do |format|
|
|
127
|
-
format.html { redirect_to action: :index }
|
|
128
|
-
format.json { render json: model.errors, status: :unprocessable_entity }
|
|
129
|
-
end
|
|
130
|
-
end
|
|
131
|
-
end
|
|
132
|
-
|
|
133
|
-
def resource_class
|
|
134
|
-
@resource_class ||= controller_name.classify.constantize
|
|
135
|
-
end
|
|
136
|
-
|
|
137
|
-
def controller_namespace
|
|
138
|
-
@controller_namespace ||= self.class.name.split('::')[0..-2].map(&:underscore).join('_') unless self.class.name.split('::')[0..-2].empty?
|
|
139
|
-
end
|
|
140
|
-
|
|
141
|
-
private
|
|
142
|
-
|
|
143
|
-
def collection=(value)
|
|
144
|
-
instance_variable_set("@#{controller_name}", value)
|
|
145
|
-
end
|
|
146
|
-
|
|
147
|
-
def collection
|
|
148
|
-
instance_variable_get("@#{controller_name}")
|
|
149
|
-
end
|
|
150
|
-
|
|
151
|
-
def model=(value)
|
|
152
|
-
instance_variable_set("@#{controller_name.singularize}", value)
|
|
153
|
-
end
|
|
154
|
-
|
|
155
|
-
def model
|
|
156
|
-
instance_variable_get("@#{controller_name.singularize}")
|
|
157
|
-
end
|
|
158
|
-
|
|
159
|
-
def load_nested
|
|
160
|
-
parent_klass = self.class.dynamic_options[:nested_of]
|
|
161
|
-
instance_variable_set("@#{parent_klass.to_s.underscore}", parent_klass.find(params["#{parent_klass.to_s.underscore}_id"]))
|
|
162
|
-
end
|
|
163
|
-
|
|
164
|
-
def parent_model
|
|
165
|
-
instance_variable_get("@#{self.class.dynamic_options[:nested_of].to_s.underscore}")
|
|
166
|
-
end
|
|
167
|
-
|
|
168
|
-
def handle_error(error)
|
|
169
|
-
respond_to do |format|
|
|
170
|
-
format.html { raise error }
|
|
171
|
-
format.json { render json: error.message, status: :internal_server_error }
|
|
172
|
-
end
|
|
173
|
-
end
|
|
174
|
-
|
|
175
|
-
end
|
|
176
|
-
|
|
177
|
-
end
|
|
178
|
-
|
|
179
|
-
ActionController::Base.send :extend, DynamicController::ClassMethods
|
|
180
|
-
|
|
1
|
+
require 'ransack'
|
|
2
|
+
require 'kaminari'
|
|
3
|
+
|
|
4
|
+
require 'dynamic_controller/version'
|
|
5
|
+
require 'dynamic_controller/resource'
|
|
6
|
+
require 'dynamic_controller/responder'
|
|
7
|
+
require 'dynamic_controller/helper_methods'
|
|
8
|
+
require 'dynamic_controller/class_methods'
|
|
9
|
+
require 'dynamic_controller/instance_methods'
|
|
10
|
+
|
|
11
|
+
ActionController::Base.send :extend, DynamicController::ClassMethods
|
|
12
|
+
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
class AllActionsController < ActionController::Base
|
|
2
|
+
has_crud_actions
|
|
3
|
+
end
|
|
4
|
+
|
|
5
|
+
class OnlyIndexController < ActionController::Base
|
|
6
|
+
has_crud_actions only: :index
|
|
7
|
+
end
|
|
8
|
+
|
|
9
|
+
class ExceptIndexController < ActionController::Base
|
|
10
|
+
has_crud_actions except: :index
|
|
11
|
+
end
|
|
12
|
+
|
|
13
|
+
class OnlyAndExceptController < ActionController::Base
|
|
14
|
+
has_crud_actions only: [:index, :new, :create, :edit], except: [:edit, :destroy]
|
|
15
|
+
end
|