authorized_rails_scaffolds 0.0.1

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 (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>