programmable_scaffold_rails 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.
- checksums.yaml +7 -0
- data/.gitignore +17 -0
- data/.rspec +2 -0
- data/.ruby-version +1 -0
- data/Gemfile +11 -0
- data/LICENSE.txt +22 -0
- data/README.md +116 -0
- data/Rakefile +1 -0
- data/config.ru +9 -0
- data/config/action_controller.yml +12 -0
- data/config/locales/en.yml +8 -0
- data/lib/programmable_scaffold_rails.rb +17 -0
- data/lib/programmable_scaffold_rails/action_controller_extensions.rb +72 -0
- data/lib/programmable_scaffold_rails/action_controller_helpers.rb +163 -0
- data/lib/programmable_scaffold_rails/config.rb +15 -0
- data/lib/programmable_scaffold_rails/engine.rb +6 -0
- data/lib/programmable_scaffold_rails/scaffold/create.rb +51 -0
- data/lib/programmable_scaffold_rails/scaffold/destroy.rb +53 -0
- data/lib/programmable_scaffold_rails/scaffold/edit.rb +21 -0
- data/lib/programmable_scaffold_rails/scaffold/index.rb +20 -0
- data/lib/programmable_scaffold_rails/scaffold/new.rb +21 -0
- data/lib/programmable_scaffold_rails/scaffold/show.rb +21 -0
- data/lib/programmable_scaffold_rails/scaffold/update.rb +49 -0
- data/lib/programmable_scaffold_rails/version.rb +3 -0
- data/programmable_scaffold_rails.gemspec +34 -0
- data/spec/action_controller_extensions.rb_spec.rb +60 -0
- data/spec/action_controller_helpers_spec.rb +90 -0
- data/spec/controllers/dummies_controller_spec.rb +416 -0
- data/spec/factories.rb +10 -0
- data/spec/internal/app/controllers/dummies_controller.rb +9 -0
- data/spec/internal/app/models/dummy.rb +11 -0
- data/spec/internal/app/views/dummies/edit.html.erb +0 -0
- data/spec/internal/app/views/dummies/index.html.erb +0 -0
- data/spec/internal/app/views/dummies/index.json.builder +4 -0
- data/spec/internal/app/views/dummies/new.html.erb +0 -0
- data/spec/internal/app/views/dummies/show.html.erb +0 -0
- data/spec/internal/app/views/dummies/show.json.builder +1 -0
- data/spec/internal/config/database.yml +4 -0
- data/spec/internal/config/routes.rb +6 -0
- data/spec/internal/db/schema.rb +7 -0
- data/spec/internal/log/.gitignore +1 -0
- data/spec/internal/public/favicon.ico +0 -0
- data/spec/programmable_scaffold_rails_spec.rb +38 -0
- data/spec/spec_helper.rb +49 -0
- metadata +276 -0
@@ -0,0 +1,15 @@
|
|
1
|
+
require 'yaml'
|
2
|
+
require 'active_support'
|
3
|
+
require 'active_support/core_ext'
|
4
|
+
|
5
|
+
module ProgrammableScaffoldRails
|
6
|
+
CRUD_METHODS = [ :new,
|
7
|
+
:create,
|
8
|
+
:index,
|
9
|
+
:show,
|
10
|
+
:edit,
|
11
|
+
:update,
|
12
|
+
:destroy ].freeze
|
13
|
+
|
14
|
+
BASE_OPTIONS = HashWithIndifferentAccess.new(YAML.load(File.read(File.expand_path('../../../config/action_controller.yml', __FILE__))))
|
15
|
+
end
|
@@ -0,0 +1,51 @@
|
|
1
|
+
require 'programmable_scaffold_rails/action_controller_helpers'
|
2
|
+
|
3
|
+
module ProgrammableScaffoldRails
|
4
|
+
|
5
|
+
module Scaffold
|
6
|
+
|
7
|
+
module Create
|
8
|
+
|
9
|
+
def create
|
10
|
+
scaffold_helper = self.programmable_scaffold_controller_helpers
|
11
|
+
self.instance_variable_set(scaffold_helper.single_instance,
|
12
|
+
scaffold_helper.klass.new(
|
13
|
+
scaffold_helper.call_strong_params
|
14
|
+
))
|
15
|
+
instance = self.instance_variable_get(scaffold_helper.single_instance)
|
16
|
+
authorize!(:create, instance) if scaffold_helper.cancan
|
17
|
+
|
18
|
+
respond_to do |format|
|
19
|
+
if instance.save
|
20
|
+
scaffold_helper.formats.each do |used_format|
|
21
|
+
case used_format
|
22
|
+
when :html
|
23
|
+
format.html { redirect_to scaffold_helper.after_create_url(instance),
|
24
|
+
notice: I18n.t('programmable_scaffold_rails.after_create_notice',
|
25
|
+
model_class: instance.class.model_name.human) }
|
26
|
+
when :json
|
27
|
+
format.json { render action: 'show', status: :created, location: instance }
|
28
|
+
end
|
29
|
+
end
|
30
|
+
else
|
31
|
+
scaffold_helper.formats.each do |used_format|
|
32
|
+
case used_format
|
33
|
+
when :html
|
34
|
+
format.html do
|
35
|
+
flash[:alert] = I18n.t('programmable_scaffold_rails.after_create_alert',
|
36
|
+
model_class: instance.class.model_name.human)
|
37
|
+
render action: 'new'
|
38
|
+
end
|
39
|
+
when :json
|
40
|
+
format.json { render json: instance.errors, status: :unprocessable_entity }
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
@@ -0,0 +1,53 @@
|
|
1
|
+
require 'programmable_scaffold_rails/action_controller_helpers'
|
2
|
+
|
3
|
+
module ProgrammableScaffoldRails
|
4
|
+
|
5
|
+
module Scaffold
|
6
|
+
|
7
|
+
module Destroy
|
8
|
+
|
9
|
+
def destroy
|
10
|
+
scaffold_helper = self.programmable_scaffold_controller_helpers
|
11
|
+
self.instance_variable_set(scaffold_helper.single_instance,
|
12
|
+
scaffold_helper.find_by_id_or_friendly_id(params))
|
13
|
+
instance = self.instance_variable_get(scaffold_helper.single_instance)
|
14
|
+
authorize!(:destroy, instance) if scaffold_helper.cancan
|
15
|
+
|
16
|
+
if instance.destroy
|
17
|
+
respond_to do |format|
|
18
|
+
scaffold_helper.formats.each do |used_format|
|
19
|
+
case used_format
|
20
|
+
when :html
|
21
|
+
format.html { redirect_to scaffold_helper.after_destroy_url(instance),
|
22
|
+
notice: I18n.t('programmable_scaffold_rails.after_destroy_notice',
|
23
|
+
model_class: instance.class.model_name.human) }
|
24
|
+
when :json
|
25
|
+
format.json { head :no_content }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
else
|
30
|
+
respond_to do |format|
|
31
|
+
scaffold_helper.formats.each do |used_format|
|
32
|
+
case used_format
|
33
|
+
when :html
|
34
|
+
# XXX: Check if redirect_to :back doesn't create issues with failing
|
35
|
+
# destroy and redirect loops
|
36
|
+
format.html do
|
37
|
+
flash[:alert] = I18n.t('programmable_scaffold_rails.after_destroy_alert',
|
38
|
+
model_class: instance.class.model_name.human)
|
39
|
+
redirect_to :back
|
40
|
+
end
|
41
|
+
when :json
|
42
|
+
format.json { render json: instance.errors, status: :unprocessable_entity }
|
43
|
+
end
|
44
|
+
end
|
45
|
+
end
|
46
|
+
end
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
50
|
+
|
51
|
+
end
|
52
|
+
|
53
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'programmable_scaffold_rails/action_controller_helpers'
|
2
|
+
|
3
|
+
module ProgrammableScaffoldRails
|
4
|
+
|
5
|
+
module Scaffold
|
6
|
+
|
7
|
+
module Edit
|
8
|
+
|
9
|
+
def edit
|
10
|
+
scaffold_helper = self.programmable_scaffold_controller_helpers
|
11
|
+
self.instance_variable_set(scaffold_helper.single_instance,
|
12
|
+
scaffold_helper.find_by_id_or_friendly_id(params))
|
13
|
+
instance = self.instance_variable_get(scaffold_helper.single_instance)
|
14
|
+
authorize!(:update, instance) if scaffold_helper.cancan
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
require 'programmable_scaffold_rails/action_controller_helpers'
|
2
|
+
|
3
|
+
module ProgrammableScaffoldRails
|
4
|
+
|
5
|
+
module Scaffold
|
6
|
+
|
7
|
+
module Index
|
8
|
+
|
9
|
+
def index
|
10
|
+
scaffold_helper = self.programmable_scaffold_controller_helpers
|
11
|
+
self.instance_variable_set(scaffold_helper.multiple_instances,
|
12
|
+
scaffold_helper.klass.all)
|
13
|
+
authorize!(:read, scaffold_helper.klass) if scaffold_helper.cancan
|
14
|
+
end
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
end
|
19
|
+
|
20
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'programmable_scaffold_rails/action_controller_helpers'
|
2
|
+
|
3
|
+
module ProgrammableScaffoldRails
|
4
|
+
|
5
|
+
module Scaffold
|
6
|
+
|
7
|
+
module New
|
8
|
+
|
9
|
+
def new
|
10
|
+
scaffold_helper = self.programmable_scaffold_controller_helpers
|
11
|
+
self.instance_variable_set(scaffold_helper.single_instance,
|
12
|
+
scaffold_helper.klass.new)
|
13
|
+
instance = self.instance_variable_get(scaffold_helper.single_instance)
|
14
|
+
authorize!(:create, instance) if scaffold_helper.cancan
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
require 'programmable_scaffold_rails/action_controller_helpers'
|
2
|
+
|
3
|
+
module ProgrammableScaffoldRails
|
4
|
+
|
5
|
+
module Scaffold
|
6
|
+
|
7
|
+
module Show
|
8
|
+
|
9
|
+
def show
|
10
|
+
scaffold_helper = self.programmable_scaffold_controller_helpers
|
11
|
+
self.instance_variable_set(scaffold_helper.single_instance,
|
12
|
+
scaffold_helper.find_by_id_or_friendly_id(params))
|
13
|
+
instance = self.instance_variable_get(scaffold_helper.single_instance)
|
14
|
+
authorize!(:read, instance) if scaffold_helper.cancan
|
15
|
+
end
|
16
|
+
|
17
|
+
end
|
18
|
+
|
19
|
+
end
|
20
|
+
|
21
|
+
end
|
@@ -0,0 +1,49 @@
|
|
1
|
+
require 'programmable_scaffold_rails/action_controller_helpers'
|
2
|
+
|
3
|
+
module ProgrammableScaffoldRails
|
4
|
+
|
5
|
+
module Scaffold
|
6
|
+
|
7
|
+
module Update
|
8
|
+
|
9
|
+
def update
|
10
|
+
scaffold_helper = self.programmable_scaffold_controller_helpers
|
11
|
+
self.instance_variable_set(scaffold_helper.single_instance,
|
12
|
+
scaffold_helper.find_by_id_or_friendly_id(params))
|
13
|
+
instance = self.instance_variable_get(scaffold_helper.single_instance)
|
14
|
+
authorize!(:update, instance) if scaffold_helper.cancan
|
15
|
+
|
16
|
+
respond_to do |format|
|
17
|
+
if instance.update(scaffold_helper.call_strong_params)
|
18
|
+
scaffold_helper.formats.each do |used_format|
|
19
|
+
case used_format
|
20
|
+
when :html
|
21
|
+
format.html { redirect_to scaffold_helper.after_update_url(instance),
|
22
|
+
notice: I18n.t('programmable_scaffold_rails.after_update_notice',
|
23
|
+
model_class: instance.class.model_name.human) }
|
24
|
+
when :json
|
25
|
+
format.json { head :no_content }
|
26
|
+
end
|
27
|
+
end
|
28
|
+
else
|
29
|
+
scaffold_helper.formats.each do |used_format|
|
30
|
+
case used_format
|
31
|
+
when :html
|
32
|
+
format.html do
|
33
|
+
flash.alert = I18n.t('programmable_scaffold_rails.after_update_alert',
|
34
|
+
model_class: instance.class.model_name.human)
|
35
|
+
render action: 'edit'
|
36
|
+
end
|
37
|
+
when :json
|
38
|
+
format.json { render json: instance.errors, status: :unprocessable_entity }
|
39
|
+
end
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|
44
|
+
|
45
|
+
end
|
46
|
+
|
47
|
+
end
|
48
|
+
|
49
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
# coding: utf-8
|
2
|
+
lib = File.expand_path('../lib', __FILE__)
|
3
|
+
$LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
|
4
|
+
require 'programmable_scaffold_rails/version'
|
5
|
+
|
6
|
+
Gem::Specification.new do |spec|
|
7
|
+
spec.name = "programmable_scaffold_rails"
|
8
|
+
spec.version = ProgrammableScaffoldRails::VERSION
|
9
|
+
spec.authors = ["Fire-Dragon-DoL"]
|
10
|
+
spec.email = ["francesco.belladonna@gmail.com"]
|
11
|
+
spec.description = %q{This gem should support you when using rails scaffold (or a lot of simple CRUD models/views/controllers) in a programmable fashion, removing repeated code when possible and making it configurable}
|
12
|
+
spec.summary = %q{This gem should remove repeated code when using Rails scaffold}
|
13
|
+
spec.homepage = "https://github.com/Fire-Dragon-DoL/programmable_scaffold_rails"
|
14
|
+
spec.license = "MIT"
|
15
|
+
|
16
|
+
spec.files = `git ls-files`.split($/)
|
17
|
+
spec.executables = spec.files.grep(%r{^bin/}) { |f| File.basename(f) }
|
18
|
+
spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
|
19
|
+
spec.require_paths = ["lib"]
|
20
|
+
|
21
|
+
spec.add_dependency "i18n", "~> 0.6.5"
|
22
|
+
spec.add_dependency "rails", "~> 4.0.0"
|
23
|
+
spec.add_dependency "activesupport", "~> 4.0.0"
|
24
|
+
|
25
|
+
spec.add_development_dependency "bundler", "~> 1.3"
|
26
|
+
spec.add_development_dependency "rspec", "~> 2.14.0"
|
27
|
+
spec.add_development_dependency "combustion", "~> 0.5.1"
|
28
|
+
spec.add_development_dependency "sqlite3", "~> 1.3.8"
|
29
|
+
spec.add_development_dependency "faker", "~> 1.2.0"
|
30
|
+
spec.add_development_dependency "factory_girl", "~> 4.3.0"
|
31
|
+
spec.add_development_dependency "database_cleaner", "~> 1.2.0"
|
32
|
+
spec.add_development_dependency "pry"
|
33
|
+
spec.add_development_dependency "rake"
|
34
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'programmable_scaffold_rails/action_controller_extensions'
|
3
|
+
|
4
|
+
describe ProgrammableScaffoldRails::ActionControllerExtensions do
|
5
|
+
let(:controller_class) do
|
6
|
+
Class.new do
|
7
|
+
include ::ProgrammableScaffoldRails::ActionControllerExtensions
|
8
|
+
end
|
9
|
+
end
|
10
|
+
# XXX: let order it's random, be careful with duping from other "lets"
|
11
|
+
let(:controller_class_with_scaffold) do
|
12
|
+
Class.new do
|
13
|
+
include ::ProgrammableScaffoldRails::ActionControllerExtensions
|
14
|
+
|
15
|
+
programmable_scaffold
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
it { controller_class.should respond_to(:programmable_scaffold) }
|
20
|
+
|
21
|
+
it "does not allow to use :extend and :only at same time in programmable_scaffold" do
|
22
|
+
expect do
|
23
|
+
controller_class.dup.class_eval do
|
24
|
+
programmable_scaffold only: [], except: []
|
25
|
+
end
|
26
|
+
end.to raise_error
|
27
|
+
end
|
28
|
+
|
29
|
+
it "does not have included Scaffold::New module because of the :only option" do
|
30
|
+
# XXX: Be careful, testing against #new method can be tricky because it
|
31
|
+
# it exists on all objects
|
32
|
+
controller_class.dup.class_eval do
|
33
|
+
programmable_scaffold only: [:create]
|
34
|
+
end.included_modules.should_not include(::ProgrammableScaffoldRails::Scaffold::New)
|
35
|
+
end
|
36
|
+
|
37
|
+
it "does not have included Scaffold::Create module because of the :except option" do
|
38
|
+
controller_class.dup.class_eval do
|
39
|
+
programmable_scaffold except: [:new]
|
40
|
+
end.included_modules.should_not include(::ProgrammableScaffoldRails::Scaffold::New)
|
41
|
+
end
|
42
|
+
|
43
|
+
context "with scaffold methods" do
|
44
|
+
subject(:controller) do
|
45
|
+
obj = controller_class_with_scaffold.new
|
46
|
+
obj.stub(:controller_name).and_return('stubbeds')
|
47
|
+
|
48
|
+
obj
|
49
|
+
end
|
50
|
+
specify { controller.should respond_to(:new) }
|
51
|
+
specify { controller.should respond_to(:create) }
|
52
|
+
specify { controller.should respond_to(:index) }
|
53
|
+
specify { controller.should respond_to(:show) }
|
54
|
+
specify { controller.should respond_to(:edit) }
|
55
|
+
specify { controller.should respond_to(:update) }
|
56
|
+
specify { controller.should respond_to(:destroy) }
|
57
|
+
|
58
|
+
end
|
59
|
+
|
60
|
+
end
|
@@ -0,0 +1,90 @@
|
|
1
|
+
require 'spec_helper'
|
2
|
+
require 'programmable_scaffold_rails/action_controller_helpers'
|
3
|
+
require 'internal/app/models/dummy'
|
4
|
+
|
5
|
+
describe ProgrammableScaffoldRails::ActionControllerHelpers do
|
6
|
+
class Stubbed
|
7
|
+
end
|
8
|
+
|
9
|
+
let(:controller_class_with_scaffold) do
|
10
|
+
Class.new do
|
11
|
+
include ::ProgrammableScaffoldRails::ActionControllerExtensions
|
12
|
+
programmable_scaffold
|
13
|
+
end
|
14
|
+
end
|
15
|
+
let(:controller) do
|
16
|
+
obj = controller_class_with_scaffold.new
|
17
|
+
obj.stub(:controller_name).and_return('stubbeds')
|
18
|
+
|
19
|
+
obj
|
20
|
+
end
|
21
|
+
let(:allowed_after_actions) { [nil, :edit, :show] }
|
22
|
+
|
23
|
+
it { controller.should respond_to(:programmable_scaffold_controller_helpers) }
|
24
|
+
|
25
|
+
subject(:controller_helpers) { controller.programmable_scaffold_controller_helpers }
|
26
|
+
specify { controller_helpers.should respond_to(:klass) }
|
27
|
+
specify { controller_helpers.should respond_to(:table) }
|
28
|
+
specify { controller_helpers.should respond_to(:single_instance_name) }
|
29
|
+
specify { controller_helpers.should respond_to(:single_instance) }
|
30
|
+
specify { controller_helpers.should respond_to(:multiple_instances_name) }
|
31
|
+
specify { controller_helpers.should respond_to(:multiple_instances) }
|
32
|
+
specify { controller_helpers.should respond_to(:url_namespace) }
|
33
|
+
specify { controller_helpers.should respond_to(:friendly_id) }
|
34
|
+
specify { controller_helpers.should respond_to(:strong_params) }
|
35
|
+
specify { controller_helpers.should respond_to(:call_strong_params) }
|
36
|
+
specify { controller_helpers.should respond_to(:cancan) }
|
37
|
+
specify { controller_helpers.should respond_to(:after_create_action) }
|
38
|
+
specify { controller_helpers.should respond_to(:after_update_action) }
|
39
|
+
specify { controller_helpers.should respond_to(:after_update_url) }
|
40
|
+
specify { controller_helpers.should respond_to(:after_create_url) }
|
41
|
+
specify { controller_helpers.should respond_to(:after_destroy_url) }
|
42
|
+
specify { controller_helpers.should respond_to(:formats) }
|
43
|
+
specify { controller_helpers.klass.should be Stubbed }
|
44
|
+
specify { controller_helpers.table.should be :stubbeds }
|
45
|
+
specify { controller_helpers.single_instance_name.should be :stubbed }
|
46
|
+
specify { controller_helpers.single_instance.should be :@stubbed }
|
47
|
+
specify { controller_helpers.multiple_instances_name.should be :stubbeds }
|
48
|
+
specify { controller_helpers.multiple_instances.should be :@stubbeds }
|
49
|
+
specify { controller_helpers.url_namespace.should match '' }
|
50
|
+
specify { controller_helpers.friendly_id.should be_false }
|
51
|
+
specify { controller_helpers.strong_params.should be :model_params }
|
52
|
+
specify { controller_helpers.cancan.should be_true }
|
53
|
+
specify { allowed_after_actions.should include(controller_helpers.after_create_action) }
|
54
|
+
specify { allowed_after_actions.should include(controller_helpers.after_update_action) }
|
55
|
+
specify { controller_helpers.formats.should match_array([:html, :json]) }
|
56
|
+
|
57
|
+
it "is valid to use nil as after_create_action" do
|
58
|
+
controller_helpers.stub(:after_create_action).and_return(nil)
|
59
|
+
allowed_after_actions.should include(controller_helpers.after_create_action)
|
60
|
+
end
|
61
|
+
|
62
|
+
it "is valid to use nil as after_update_action" do
|
63
|
+
controller_helpers.stub(:after_update_action).and_return(nil)
|
64
|
+
allowed_after_actions.should include(controller_helpers.after_update_action)
|
65
|
+
end
|
66
|
+
|
67
|
+
it "has not implemented strong_params method that will be called" do
|
68
|
+
expect do
|
69
|
+
controller_helpers.call_strong_params
|
70
|
+
end.to raise_error(NotImplementedError)
|
71
|
+
end
|
72
|
+
|
73
|
+
context "when searching in database" do
|
74
|
+
subject(:dummy_model) { Stubbed.new }
|
75
|
+
|
76
|
+
it "can search item without slug" do
|
77
|
+
controller_helpers.stub_chain('klass.find').and_return(dummy_model)
|
78
|
+
|
79
|
+
controller_helpers.find_by_id_or_friendly_id({ id: 1 }).should be dummy_model
|
80
|
+
end
|
81
|
+
|
82
|
+
it "can search item with slug" do
|
83
|
+
controller_helpers.stub(:friendly_id).and_return(true)
|
84
|
+
controller_helpers.stub_chain('klass.friendly.find').and_return(dummy_model)
|
85
|
+
|
86
|
+
controller_helpers.find_by_id_or_friendly_id({ id: 'dummy' }).should be dummy_model
|
87
|
+
end
|
88
|
+
end
|
89
|
+
|
90
|
+
end
|