authorized_rails_scaffolds 0.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (24) hide show
  1. data/.gitignore +19 -0
  2. data/Gemfile +4 -0
  3. data/LICENSE.txt +22 -0
  4. data/README.md +101 -0
  5. data/Rakefile +1 -0
  6. data/authorized_rails_scaffolds.gemspec +24 -0
  7. data/lib/authorized_rails_scaffolds.rb +5 -0
  8. data/lib/authorized_rails_scaffolds/version.rb +3 -0
  9. data/lib/generators/authorized_rails_scaffolds/install_scaffold/USAGE +9 -0
  10. data/lib/generators/authorized_rails_scaffolds/install_scaffold/install_scaffold_generator.rb +26 -0
  11. data/lib/generators/authorized_rails_scaffolds/install_scaffold/templates/_form.html.erb +18 -0
  12. data/lib/generators/authorized_rails_scaffolds/install_scaffold/templates/controller.rb +107 -0
  13. data/lib/generators/authorized_rails_scaffolds/install_scaffold/templates/edit.html.erb +5 -0
  14. data/lib/generators/authorized_rails_scaffolds/install_scaffold/templates/index.html.erb +52 -0
  15. data/lib/generators/authorized_rails_scaffolds/install_scaffold/templates/new.html.erb +5 -0
  16. data/lib/generators/authorized_rails_scaffolds/install_scaffold/templates/show.html.erb +34 -0
  17. data/lib/generators/authorized_rails_scaffolds/install_spec/USAGE +9 -0
  18. data/lib/generators/authorized_rails_scaffolds/install_spec/install_spec_generator.rb +18 -0
  19. data/lib/generators/authorized_rails_scaffolds/install_spec/templates/controller_spec.rb +358 -0
  20. data/lib/generators/authorized_rails_scaffolds/install_spec/templates/edit_spec.rb +99 -0
  21. data/lib/generators/authorized_rails_scaffolds/install_spec/templates/index_spec.rb +185 -0
  22. data/lib/generators/authorized_rails_scaffolds/install_spec/templates/new_spec.rb +98 -0
  23. data/lib/generators/authorized_rails_scaffolds/install_spec/templates/show_spec.rb +64 -0
  24. metadata +103 -0
data/.gitignore ADDED
@@ -0,0 +1,19 @@
1
+ .DS_Store
2
+ ._*
3
+ *.gem
4
+ *.rbc
5
+ .bundle
6
+ .config
7
+ .yardoc
8
+ Gemfile.lock
9
+ InstalledFiles
10
+ _yardoc
11
+ coverage
12
+ doc/
13
+ lib/bundler/man
14
+ pkg
15
+ rdoc
16
+ spec/reports
17
+ test/tmp
18
+ test/version_tmp
19
+ tmp
data/Gemfile ADDED
@@ -0,0 +1,4 @@
1
+ source 'https://rubygems.org'
2
+
3
+ # Specify your gem's dependencies in authorized_rails_scaffolds.gemspec
4
+ gemspec
data/LICENSE.txt ADDED
@@ -0,0 +1,22 @@
1
+ Copyright (c) 2013 Ben Morrall
2
+
3
+ MIT License
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ "Software"), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
20
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
21
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
22
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/README.md ADDED
@@ -0,0 +1,101 @@
1
+ # authorized_rails_scaffolds
2
+
3
+ Replaces Rails and RSpec's default generators with templates taking full advantage of Authentication, Authorization and Test Coverage.
4
+
5
+ Originally Developed for Devise, CanCan and RSpec, the generated templates can be changed to handle most authorization, authentication and testing solutions with minimal effort.
6
+
7
+ ## Features
8
+
9
+ ### No Namespacing of Models
10
+
11
+ - Removes the Controller's namespace from the generated Controllers, allowing `rails g scaffold_controller admin/example` to handle `Example` models by default.
12
+
13
+ ### Better RSpec Coverage for generated Controllers and Views
14
+
15
+ - Standard behaviour is tested to ensure that all code functions as expected
16
+ - Authenticated is tested, to ensure that users are refused access until they have signed in.
17
+ - Authorization is tested, to ensure that users are only able to view content if they have access to it.
18
+
19
+ ## Installation
20
+
21
+ Add this line to your application's Gemfile:
22
+
23
+ gem 'authorized_rails_scaffolds', :group => :development
24
+
25
+ And then execute:
26
+
27
+ $ bundle
28
+
29
+ Or install it yourself as:
30
+
31
+ $ gem install authorized_rails_scaffolds
32
+
33
+ ## Usage
34
+
35
+ `authorized_rails_scaffolds` is a development only gem that adds templates for quickly creating new controllers and views to be displayed primarily viewed with Twitter Bootstrap.
36
+
37
+ Once you have run all the generators you want, you can remove the gem with no side effects.
38
+
39
+ ### Install Scaffold Templates
40
+
41
+ `authorized_rails_scaffolds` provides a series of rails generators that replace the default scaffold templates generated by Rails.
42
+
43
+ The generated Controllers require CanCan to be installed on your system, however it is possible change this behavour by uncommenting out the first line of each generated action manually.
44
+
45
+ The generated Controller only handles Authorization and assumes Authentication is managed in the Application Controller or is added manually.
46
+
47
+ You can install the generators by running:
48
+
49
+ $ rails generate authorized_rails_scaffolds:install_scaffold
50
+
51
+ This gem doesn't override the default scaffold.css generated by `rails g scaffold`, however it works best with `rails g scaffold_controller`.
52
+
53
+ For example:
54
+
55
+ rails g model FooBar name:string age:integer date_of_birth:date lunch_time:time programmer:boolean joined_at:datetime
56
+ rails g scaffold_controller Awesome/FooBar name:string age:integer date_of_birth:date lunch_time:time programmer:boolean joined_at:datetime
57
+
58
+ ### Install Spec Temlates
59
+
60
+ `authorized_rails_scaffolds` provides a series of rspec generators that replace the default controller and view spec templates generated by RSpec. It will also add a ControllerMacros spec support helper to login and logout users.
61
+
62
+ The generated specs assume you are have a FactoryGirl factory called `user`.
63
+
64
+ You can install the generators by running:
65
+
66
+ $ rails generate authorized_rails_scaffolds:install_spec
67
+
68
+ You will need to implement `login_unauthorized_user` and `login_user_with_ability` into your Controller specs.
69
+
70
+ Installing Scaffold Controllers in Rails (`rails g scaffold_controller`) generates view and controller specs if RSpec is installed as a gem.
71
+
72
+ ## Contributing
73
+
74
+ 1. Fork it
75
+ 2. Create your feature branch (`git checkout -b my-new-feature`)
76
+ 3. Commit your changes (`git commit -am 'Add some feature'`)
77
+ 4. Push to the branch (`git push origin my-new-feature`)
78
+ 5. Create new Pull Request
79
+
80
+ ## License
81
+
82
+ Copyright (c) 2013 Ben Morrall
83
+
84
+ Permission is hereby granted, free of charge, to any person obtaining
85
+ a copy of this software and associated documentation files (the
86
+ "Software"), to deal in the Software without restriction, including
87
+ without limitation the rights to use, copy, modify, merge, publish,
88
+ distribute, sublicense, and/or sell copies of the Software, and to
89
+ permit persons to whom the Software is furnished to do so, subject to
90
+ the following conditions:
91
+
92
+ The above copyright notice and this permission notice shall be
93
+ included in all copies or substantial portions of the Software.
94
+
95
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
96
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
97
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
98
+ NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
99
+ LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
100
+ OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
101
+ WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
data/Rakefile ADDED
@@ -0,0 +1 @@
1
+ require "bundler/gem_tasks"
@@ -0,0 +1,24 @@
1
+ # coding: utf-8
2
+ lib = File.expand_path('../lib', __FILE__)
3
+ $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
4
+ require 'authorized_rails_scaffolds/version'
5
+
6
+ Gem::Specification.new do |spec|
7
+ spec.name = "authorized_rails_scaffolds"
8
+ spec.version = AuthorizedRailsScaffolds::VERSION
9
+ spec.authors = ["bmorrall"]
10
+ spec.email = ["bemo56@hotmail.com"]
11
+ spec.description = %q{Creates scaffolds for Twitter Bootstrap with generated RSpec coverage}
12
+ spec.summary = %q{Replaces Rails and RSpec's default generators with templates taking full advantage of Authentication (Devise), Authorization (CanCan) and Test Coverage (RSpec)}
13
+ spec.homepage = "https://github.com/bmorrall/authorized_rails_scaffolds"
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 'railties', '>= 3.1'
22
+ spec.add_development_dependency "bundler", "~> 1.3"
23
+ spec.add_development_dependency "rake"
24
+ end
@@ -0,0 +1,5 @@
1
+ require "authorized_rails_scaffolds/version"
2
+
3
+ module AuthorizedRailsScaffolds
4
+ # Your code goes here...
5
+ end
@@ -0,0 +1,3 @@
1
+ module AuthorizedRailsScaffolds
2
+ VERSION = "0.0.1"
3
+ end
@@ -0,0 +1,9 @@
1
+ Description:
2
+ Installs scaffold templates that take advantage of Devise, CanCan and RSpec.
3
+
4
+ Example:
5
+ rails generate authorized_rails_scaffolds:install_templates
6
+
7
+ This will create:
8
+ ERB view templates in lib/erb/scaffold
9
+ Scaffold controller templates in lib/rails/scaffold_controller
@@ -0,0 +1,26 @@
1
+ class AuthorizedRailsScaffolds::InstallScaffoldGenerator < Rails::Generators::Base
2
+ source_root File.expand_path('../templates', __FILE__)
3
+
4
+ def create_erb_templates
5
+ copy_erb_template '_form.html.erb'
6
+ copy_erb_template 'edit.html.erb'
7
+ copy_erb_template 'index.html.erb'
8
+ copy_erb_template 'new.html.erb'
9
+ copy_erb_template 'show.html.erb'
10
+ end
11
+
12
+ def create_rails_templates
13
+ copy_rspec_template 'controller.rb'
14
+ end
15
+
16
+ protected
17
+
18
+ def copy_erb_template(template_name)
19
+ copy_file template_name, "lib/templates/erb/scaffold/#{template_name}"
20
+ end
21
+
22
+ def copy_rails_template(template_name)
23
+ copy_file template_name, "lib/templates/rails/scaffold_controller/#{template_name}"
24
+ end
25
+
26
+ end
@@ -0,0 +1,18 @@
1
+ <%- singular_var_name = file_name -%>
2
+ <%- a = singular_table_name.split(file_name, -1)[0..-2].join(file_name) %>
3
+ <%- form_object_vars = a.blank? ? "@#{singular_var_name}" : "[:#{a.split('_').join(', :')}, @#{singular_var_name}]" -%>
4
+ <%%= simple_form_for(<%= form_object_vars %>, :html => { class: 'form-horizontal' }) do |f| %>
5
+ <%%= f.error_notification %>
6
+
7
+ <div class="form-inputs">
8
+ <%- attributes.each do |attribute| -%>
9
+ <%%= f.<%= attribute.reference? ? :association : :input %> :<%= attribute.name %> %>
10
+ <%- end -%>
11
+ </div>
12
+
13
+ <div class="form-actions">
14
+ <%%= f.button :submit, :class => 'btn-primary' %>
15
+ <%%= link_to t('.cancel', :default => t("helpers.links.cancel")),
16
+ <%= index_helper %>_path, :class => 'btn' %>
17
+ </div>
18
+ <%% end %>
@@ -0,0 +1,107 @@
1
+ <% if namespaced? -%>
2
+ require_dependency "<%= namespaced_file_path %>/application_controller"
3
+
4
+ <% end -%>
5
+ <%- singular_var_name = file_name -%>
6
+ <%- plural_var_name = file_name.pluralize -%>
7
+ <%- local_class_name = class_name.split("::")[-1] -%>
8
+ <%- orm_instance = Rails::Generators::ActiveModel.new singular_var_name -%>
9
+ <% module_namespacing do -%>
10
+ class <%= controller_class_name %>Controller < ApplicationController
11
+ load_and_authorize_resource
12
+
13
+ # GET <%= route_url %>
14
+ # GET <%= route_url %>.json
15
+ def index
16
+ # @<%= plural_var_name %> = <%= orm_class.all(local_class_name) %>
17
+
18
+ respond_to do |format|
19
+ format.html # index.html.erb
20
+ format.json { render <%= key_value :json, "@#{plural_var_name}" %> }
21
+ end
22
+ end
23
+
24
+ # GET <%= route_url %>/1
25
+ # GET <%= route_url %>/1.json
26
+ def show
27
+ # @<%= singular_var_name %> = <%= orm_class.find(local_class_name, "params[:id]") %>
28
+
29
+ respond_to do |format|
30
+ format.html # show.html.erb
31
+ format.json { render <%= key_value :json, "@#{singular_var_name}" %> }
32
+ end
33
+ end
34
+
35
+ # GET <%= route_url %>/new
36
+ # GET <%= route_url %>/new.json
37
+ def new
38
+ # @<%= singular_var_name %> = <%= orm_class.build(local_class_name) %>
39
+
40
+ respond_to do |format|
41
+ format.html # new.html.erb
42
+ format.json { render <%= key_value :json, "@#{singular_var_name}" %> }
43
+ end
44
+ end
45
+
46
+ # GET <%= route_url %>/1/edit
47
+ def edit
48
+ # @<%= singular_var_name %> = <%= orm_class.find(local_class_name, "params[:id]") %>
49
+ end
50
+
51
+ # POST <%= route_url %>
52
+ # POST <%= route_url %>.json
53
+ def create
54
+ # @<%= singular_var_name %> = <%= orm_class.build(local_class_name, "params[:#{singular_var_name}]") %>
55
+
56
+ respond_to do |format|
57
+ if @<%= orm_instance.save %>
58
+ format.html { redirect_to <%= singular_table_name %>_path(@<%= singular_var_name %>), <%= key_value :notice, "'#{human_name} was successfully created.'" %> }
59
+ format.json { render <%= key_value :json, "@#{singular_var_name}" %>, <%= key_value :status, ':created' %>, <%= key_value :location, "#{singular_table_name}_path(@#{singular_var_name})" %> }
60
+ else
61
+ format.html { render <%= key_value :action, '"new"' %> }
62
+ format.json { render <%= key_value :json, "@#{orm_instance.errors}" %>, <%= key_value :status, ':unprocessable_entity' %> }
63
+ end
64
+ end
65
+ end
66
+
67
+ # PUT <%= route_url %>/1
68
+ # PUT <%= route_url %>/1.json
69
+ def update
70
+ # @<%= singular_var_name %> = <%= orm_class.find(local_class_name, "params[:id]") %>
71
+
72
+ respond_to do |format|
73
+ if @<%= orm_instance.update_attributes("params[:#{singular_var_name}]") %>
74
+ format.html { redirect_to <%= singular_table_name %>_path(@<%= singular_var_name %>), <%= key_value :notice, "'#{human_name} was successfully updated.'" %> }
75
+ format.json { head :no_content }
76
+ else
77
+ format.html { render <%= key_value :action, '"edit"' %> }
78
+ format.json { render <%= key_value :json, "@#{orm_instance.errors}" %>, <%= key_value :status, ':unprocessable_entity' %> }
79
+ end
80
+ end
81
+ end
82
+
83
+ # DELETE <%= route_url %>/1
84
+ # DELETE <%= route_url %>/1.json
85
+ def destroy
86
+ # @<%= singular_var_name %> = <%= orm_class.find(local_class_name, "params[:id]") %>
87
+ @<%= orm_instance.destroy %>
88
+
89
+ respond_to do |format|
90
+ format.html { redirect_to <%= index_helper %>_url }
91
+ format.json { head :no_content }
92
+ end
93
+ end
94
+
95
+ protected
96
+
97
+ # Capture any access violations, ensure User isn't unnessisarily redirected to root
98
+ rescue_from CanCan::AccessDenied do |exception|
99
+ if params[:action] == 'index'
100
+ redirect_to root_url, :alert => exception.message
101
+ else
102
+ redirect_to <%= index_helper %>_url, :alert => exception.message
103
+ end
104
+ end
105
+
106
+ end
107
+ <% end -%>
@@ -0,0 +1,5 @@
1
+ <%%- model_class = <%= file_name.classify %> -%>
2
+ <div class="page-header">
3
+ <h1><%%=t '.title', :default => [:'helpers.titles.edit', 'Edit %{model}'], :model => model_class.model_name.human %></h1>
4
+ </div>
5
+ <%%= render :partial => 'form' %>
@@ -0,0 +1,52 @@
1
+ <%- singular_var_name = file_name -%>
2
+ <%- plural_var_name = file_name.pluralize-%>
3
+ <%%- model_class = <%= file_name.classify %> -%>
4
+ <div class="page-header">
5
+ <h1><%%=t '.title', :default => model_class.model_name.human.pluralize %></h1>
6
+ </div>
7
+ <table class="table table-striped">
8
+ <thead>
9
+ <tr>
10
+ <th>&nbsp;</th>
11
+ <%- attributes.each do |attribute| -%>
12
+ <th><%%= model_class.human_attribute_name(:<%= attribute.name %>) %></th>
13
+ <%- end -%>
14
+ <th><%%= model_class.human_attribute_name(:created_at) %></th>
15
+ <th><%%=t '.actions', :default => t("helpers.actions") %></th>
16
+ </tr>
17
+ </thead>
18
+ <tbody>
19
+ <%% @<%= plural_var_name %>.each do |<%= singular_var_name %>| %>
20
+ <tr class="<%= singular_var_name %>_<%%= <%= singular_var_name%>.id %>">
21
+ <td class="id-column"><%%= <%= singular_var_name %>.id %></td>
22
+ <%- if attributes.any? -%>
23
+ <td class="title-column"><%%= link_to <%= singular_var_name %>.<%= attributes[0].name %>, <%= singular_table_name %>_path(<%= singular_var_name %>) %></td>
24
+ <%- attributes[1..-1].each do |attribute| -%>
25
+ <%- if [:datetime, :timestamp, :time, :date].include? attribute.type -%>
26
+ <td><%%=l <%= singular_var_name %>.<%= attribute.name %><% if attribute.type == :datetime %>, :format => :long<% end %><% if attribute.type == :time %>, :format => :short<% end %> %></td>
27
+ <%- else -%>
28
+ <td><%%= <%= singular_var_name %>.<%= attribute.name %> %></td>
29
+ <%- end -%>
30
+ <%- end -%>
31
+ <%- end -%>
32
+ <td><%%=l <%= singular_var_name %>.created_at %></td>
33
+ <td class="table-actions">
34
+ <%%= link_to t('.edit', :default => t("helpers.links.edit")),
35
+ edit_<%= singular_table_name %>_path(<%= singular_var_name %>), :class => 'btn btn-mini', :disabled => !can?(:update, <%= singular_var_name %>) %>
36
+ <%%= link_to t('.destroy', :default => t("helpers.links.destroy")),
37
+ <%= singular_table_name %>_path(<%= singular_var_name %>),
38
+ :method => :delete,
39
+ :data => { :confirm => t('.confirm', :default => t("helpers.links.confirm", :default => 'Are you sure?')) },
40
+ :class => 'btn btn-mini btn-danger',
41
+ :disabled => !can?(:destroy, <%= singular_var_name %>) %>
42
+ </td>
43
+ </tr>
44
+ <%% end %>
45
+ </tbody>
46
+ </table>
47
+
48
+ <%% if can?(:create, <%= file_name.classify %>) %>
49
+ <%%= link_to t('.new', :default => t("helpers.links.new")),
50
+ new_<%= singular_table_name %>_path,
51
+ :class => 'btn btn-primary' %>
52
+ <%% end %>
@@ -0,0 +1,5 @@
1
+ <%%- model_class = <%= file_name.classify %> -%>
2
+ <div class="page-header">
3
+ <h1><%%=t '.title', :default => [:'helpers.titles.new', 'New %{model}'], :model => model_class.model_name.human %></h1>
4
+ </div>
5
+ <%%= render :partial => 'form' %>
@@ -0,0 +1,34 @@
1
+ <%- singular_var_name = file_name -%>
2
+ <%%- model_class = <%= file_name.classify %> -%>
3
+ <div class="page-header">
4
+ <h1><%%=t '.title', :default => model_class.model_name.human %></h1>
5
+ </div>
6
+
7
+ <dl class="dl-horizontal item-summary">
8
+ <%- attributes.each do |attribute| -%>
9
+ <dt><strong><%%= model_class.human_attribute_name(:<%= attribute.name %>) %>:</strong></dt>
10
+ <%- if [:datetime, :timestamp, :time, :date].include? attribute.type -%>
11
+ <%% unless @<%= singular_var_name %>.nil? %>
12
+ <dd><%%=l @<%= singular_var_name %>.<%= attribute.name %><% if attribute.type == :datetime %>, :format => :long<% end %><% if attribute.type == :time %>, :format => :short<% end %> %></dd>
13
+ <%% end %>
14
+ <%- else -%>
15
+ <dd><%%= @<%= singular_var_name %>.<%= attribute.name %> %></dd>
16
+ <%- end -%>
17
+ <%- end -%>
18
+ </dl>
19
+
20
+ <div class="form-actions">
21
+ <%%= link_to t('.back', :default => t("helpers.links.back")),
22
+ <%= index_helper %>_path, :class => 'btn' %>
23
+ <%% if can? :update, @<%= singular_var_name %> %>
24
+ <%%= link_to t('.edit', :default => t("helpers.links.edit")),
25
+ edit_<%= singular_table_name %>_path(@<%= singular_var_name %>), :class => 'btn' %>
26
+ <%% end %>
27
+ <%% if can? :destroy, @<%= singular_var_name %> %>
28
+ <%%= link_to t('.destroy', :default => t("helpers.links.destroy")),
29
+ <%= singular_table_name %>_path(@<%= singular_var_name %>),
30
+ :method => 'delete',
31
+ :data => { :confirm => t('.confirm', :default => t("helpers.links.confirm", :default => 'Are you sure?')) },
32
+ :class => 'act act-danger pull-right' %>
33
+ <%% end %>
34
+ </div>