abstracted 0.0.4
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/.envrc +1 -0
- data/.gitignore +8 -0
- data/.rspec +3 -0
- data/.ruby-version +1 -0
- data/Gemfile +14 -0
- data/Gemfile.lock +218 -0
- data/Guardfile +77 -0
- data/MIT-LICENSE +20 -0
- data/README.rdoc +3 -0
- data/Rakefile +15 -0
- data/abstracted.gemspec +51 -0
- data/app/assets/images/abstracted/.keep +0 -0
- data/app/assets/javascripts/abstract_resources.js +39 -0
- data/app/assets/javascripts/abstracted/.keep +0 -0
- data/app/assets/javascripts/crud.js.coffee +49 -0
- data/app/assets/javascripts/initializers.js.coffee +111 -0
- data/app/assets/stylesheets/abstract_resources.css +5 -0
- data/app/assets/stylesheets/abstracted/.keep +0 -0
- data/app/assets/stylesheets/scaffold.css +56 -0
- data/app/controllers/.keep +0 -0
- data/app/controllers/abstract_resources_controller.rb +290 -0
- data/app/controllers/application_controller.rb +22 -0
- data/app/helpers/.keep +0 -0
- data/app/helpers/abstract_resources_helper.rb +26 -0
- data/app/mailers/.keep +0 -0
- data/app/models/.keep +0 -0
- data/app/models/abstract_resource.rb +122 -0
- data/app/models/concerns/roleable.rb +61 -0
- data/app/policies/abstract_resource_policy.rb +58 -0
- data/app/views/.keep +0 -0
- data/app/views/abstract_resources/_default.html.erb +11 -0
- data/app/views/abstract_resources/destroy.js.haml +1 -0
- data/app/views/abstract_resources/edit.html.haml +11 -0
- data/app/views/abstract_resources/index.html.erb +1 -0
- data/app/views/abstract_resources/new.html.haml +12 -0
- data/app/views/abstract_resources/show.html.haml +13 -0
- data/bin/rails +12 -0
- data/config/locales/abstracted.en.yml +20 -0
- data/config/routes.rb +4 -0
- data/lib/abstracted.rb +8 -0
- data/lib/abstracted/engine.rb +19 -0
- data/lib/abstracted/version.rb +3 -0
- data/lib/abstracted_responder.rb +7 -0
- data/lib/tasks/abstracted_tasks.rake +4 -0
- data/spec/controllers/abstract_resources_controller_spec.rb +241 -0
- data/spec/dummy/README.rdoc +28 -0
- data/spec/dummy/Rakefile +6 -0
- data/spec/dummy/app/assets/images/.keep +0 -0
- data/spec/dummy/app/assets/javascripts/application.js +13 -0
- data/spec/dummy/app/assets/stylesheets/application.css +15 -0
- data/spec/dummy/app/controllers/application_controller.rb +5 -0
- data/spec/dummy/app/controllers/concerns/.keep +0 -0
- data/spec/dummy/app/helpers/application_helper.rb +2 -0
- data/spec/dummy/app/mailers/.keep +0 -0
- data/spec/dummy/app/models/.keep +0 -0
- data/spec/dummy/app/models/concerns/.keep +0 -0
- data/spec/dummy/app/models/user.rb +3 -0
- data/spec/dummy/app/views/layouts/application.html.erb +14 -0
- data/spec/dummy/bin/bundle +3 -0
- data/spec/dummy/bin/rails +4 -0
- data/spec/dummy/bin/rake +4 -0
- data/spec/dummy/bin/setup +29 -0
- data/spec/dummy/config.ru +4 -0
- data/spec/dummy/config/application.rb +26 -0
- data/spec/dummy/config/boot.rb +5 -0
- data/spec/dummy/config/database.yml +25 -0
- data/spec/dummy/config/environment.rb +5 -0
- data/spec/dummy/config/environments/development.rb +41 -0
- data/spec/dummy/config/environments/production.rb +79 -0
- data/spec/dummy/config/environments/test.rb +42 -0
- data/spec/dummy/config/initializers/assets.rb +11 -0
- data/spec/dummy/config/initializers/backtrace_silencers.rb +7 -0
- data/spec/dummy/config/initializers/cookies_serializer.rb +3 -0
- data/spec/dummy/config/initializers/filter_parameter_logging.rb +4 -0
- data/spec/dummy/config/initializers/inflections.rb +16 -0
- data/spec/dummy/config/initializers/mime_types.rb +4 -0
- data/spec/dummy/config/initializers/session_store.rb +3 -0
- data/spec/dummy/config/initializers/wrap_parameters.rb +14 -0
- data/spec/dummy/config/locales/en.yml +23 -0
- data/spec/dummy/config/routes.rb +56 -0
- data/spec/dummy/config/secrets.yml +22 -0
- data/spec/dummy/db/development.sqlite3 +0 -0
- data/spec/dummy/db/schema.rb +21 -0
- data/spec/dummy/db/test.sqlite3 +0 -0
- data/spec/dummy/lib/assets/.keep +0 -0
- data/spec/dummy/log/.keep +0 -0
- data/spec/dummy/log/development.log +0 -0
- data/spec/dummy/log/test.log +6229 -0
- data/spec/dummy/public/404.html +67 -0
- data/spec/dummy/public/422.html +67 -0
- data/spec/dummy/public/500.html +66 -0
- data/spec/dummy/public/favicon.ico +0 -0
- data/spec/factories/abstract_resources.rb +6 -0
- data/spec/factories/users.rb +5 -0
- data/spec/features/posts/manage_posts_spec.rb +24 -0
- data/spec/models/abstract_resource_spec.rb +14 -0
- data/spec/rails_helper.rb +114 -0
- data/spec/spec_helper.rb +97 -0
- data/test/integration/abstract_resource_test.rb +7 -0
- metadata +424 -0
@@ -0,0 +1,22 @@
|
|
1
|
+
require 'pundit'
|
2
|
+
class ApplicationController < ActionController::Base
|
3
|
+
# Prevent CSRF attacks by raising an exception.
|
4
|
+
# For APIs, you may want to use :null_session instead.
|
5
|
+
protect_from_forgery with: :exception
|
6
|
+
|
7
|
+
#
|
8
|
+
# Pundit implementation
|
9
|
+
#
|
10
|
+
include Pundit
|
11
|
+
rescue_from Pundit::NotAuthorizedError, with: :user_not_authorized
|
12
|
+
|
13
|
+
private
|
14
|
+
|
15
|
+
def user_not_authorized(exception)
|
16
|
+
policy_name = exception.policy.class.to_s.underscore
|
17
|
+
|
18
|
+
flash[:error] = t '.not_authorized' #t "#{policy_name}.#{exception.query}", scope: "pundit", default: :default
|
19
|
+
redirect_to(request.referrer || "/pages/error", flash: flash)
|
20
|
+
end
|
21
|
+
|
22
|
+
end
|
data/app/helpers/.keep
ADDED
File without changes
|
@@ -0,0 +1,26 @@
|
|
1
|
+
module AbstractResourcesHelper
|
2
|
+
|
3
|
+
#
|
4
|
+
# URL Helpers
|
5
|
+
def edit_resource_url(options={})
|
6
|
+
options[:action] ||= :edit
|
7
|
+
options[:controller] ||= @resource_class.table_name
|
8
|
+
url_for options
|
9
|
+
end
|
10
|
+
|
11
|
+
def resources_url resources=@resources, options={}
|
12
|
+
options[:controller] ||= @resource_class.table_name
|
13
|
+
url_for options
|
14
|
+
end
|
15
|
+
|
16
|
+
|
17
|
+
#
|
18
|
+
# Resource Helpers
|
19
|
+
def resource
|
20
|
+
@resource
|
21
|
+
end
|
22
|
+
|
23
|
+
def resources
|
24
|
+
@resources
|
25
|
+
end
|
26
|
+
end
|
data/app/mailers/.keep
ADDED
File without changes
|
data/app/models/.keep
ADDED
File without changes
|
@@ -0,0 +1,122 @@
|
|
1
|
+
class AbstractResource < ActiveRecord::Base
|
2
|
+
self.abstract_class=true
|
3
|
+
#
|
4
|
+
# include Exceptions
|
5
|
+
# include PrintEngine
|
6
|
+
#
|
7
|
+
# belongs_to :ox
|
8
|
+
# has_many :eventables, as: :eventable
|
9
|
+
#
|
10
|
+
# #
|
11
|
+
# # translate the key
|
12
|
+
# def self.oxt(key, *args)
|
13
|
+
# I18n.t(key, args[0])
|
14
|
+
# end
|
15
|
+
#
|
16
|
+
# def oxt(key, *args)
|
17
|
+
# self.class.oxt(key, args[0])
|
18
|
+
# end
|
19
|
+
#
|
20
|
+
# #
|
21
|
+
# # when implementing searches on models (using params)
|
22
|
+
# def self.find_with_params(params=nil)
|
23
|
+
# all
|
24
|
+
# end
|
25
|
+
#
|
26
|
+
#
|
27
|
+
# def self.logit( log_type, msg )
|
28
|
+
# Rails.logger.send(log_type, "[OXEN] #{Time.now} [#{log_type.to_s}] #{msg}")
|
29
|
+
# end
|
30
|
+
#
|
31
|
+
# def logit( log_type, msg )
|
32
|
+
# Rails.logger.send(log_type, "[OXEN] #{Time.now} [#{log_type.to_s}] #{msg}")
|
33
|
+
# end
|
34
|
+
#
|
35
|
+
#
|
36
|
+
#
|
37
|
+
# # list_title
|
38
|
+
# def list_title
|
39
|
+
# self.respond_to?( "name") ? self.name : "please define list_title on model (#{self.class.to_s})!"
|
40
|
+
# end
|
41
|
+
#
|
42
|
+
# # implement on relevant models
|
43
|
+
# def default_record_template
|
44
|
+
# '/record.html.haml'
|
45
|
+
# end
|
46
|
+
#
|
47
|
+
# def self.default_list_template
|
48
|
+
# 'list.html.haml'
|
49
|
+
# end
|
50
|
+
#
|
51
|
+
# def self.default_label_template
|
52
|
+
# 'label.html.haml'
|
53
|
+
# end
|
54
|
+
#
|
55
|
+
# def print_label options={}
|
56
|
+
# params = {}
|
57
|
+
# params[:print_job] = {}
|
58
|
+
# params[:print_job][:view_template_path] = options[:template] || default_label_template
|
59
|
+
# params[:print_job][:print_driver] = options[:print_driver] || :cab
|
60
|
+
# params[:print_job][:print_format] = options[:print_format] || 'label'
|
61
|
+
# params[:print_job][:paper] = options[:paper] || "Pakkelabel"
|
62
|
+
# params[:printer_name] = options[:printer_name]
|
63
|
+
# params[:user] = options[:user]
|
64
|
+
# self.class.print [self], params
|
65
|
+
# end
|
66
|
+
#
|
67
|
+
# def print_record(options={})
|
68
|
+
# params = {}
|
69
|
+
# params[:print_job] = {}
|
70
|
+
# params[:print_job][:view_template_path] = options[:template] || default_record_template
|
71
|
+
# params[:print_job][:print_driver] = options[:print_driver] || :pdf
|
72
|
+
# params[:print_job][:print_format] = options[:print_format] || 'sheet'
|
73
|
+
# params[:print_job][:paper] = options[:paper] || "A4"
|
74
|
+
# params[:printer_name] = options[:printer_name]
|
75
|
+
# params[:user] = options[:user]
|
76
|
+
# self.class.print [self], params
|
77
|
+
# end
|
78
|
+
#
|
79
|
+
# def self.print_list(options={})
|
80
|
+
# params = {}
|
81
|
+
# params[:print_job] = {}
|
82
|
+
# params[:print_job][:view_template_path] = options[:template] || self.default_list_template
|
83
|
+
# params[:print_job][:print_driver] = options[:print_driver] || :pdf
|
84
|
+
# params[:print_job][:print_format] = options[:print_format] || 'list'
|
85
|
+
# params[:print_job][:paper] = options[:paper] || "A4"
|
86
|
+
# params[:printer_name] = options[:printer_name]
|
87
|
+
# params[:user] = options[:user]
|
88
|
+
# self.print options[:resources], params
|
89
|
+
# end
|
90
|
+
#
|
91
|
+
# # add the child to an association of children
|
92
|
+
# def attach child
|
93
|
+
# case child.class.to_s
|
94
|
+
# when "Event","WageEvent"
|
95
|
+
# Eventable.create( event: child, eventable: self) unless child.eventables.include?( self)
|
96
|
+
# when "Printer"
|
97
|
+
# Printable.create( printer: child, printable: self) unless child.printables.include?( self)
|
98
|
+
# else
|
99
|
+
# children = eval child.class.to_s.underscore.pluralize
|
100
|
+
# children << child
|
101
|
+
# end
|
102
|
+
# end
|
103
|
+
#
|
104
|
+
# # remove the child from an association of children
|
105
|
+
# def detach child
|
106
|
+
# case child.class.to_s
|
107
|
+
# when "Event","WageEvent"
|
108
|
+
# ev = Eventable.where( event: child, eventable: self)
|
109
|
+
# ev.delete_all
|
110
|
+
# when "Printer"
|
111
|
+
# pr = Printable.where( printer: child, printable: self)
|
112
|
+
# pr.delete_all
|
113
|
+
# else
|
114
|
+
# children = eval child.class.to_s.downcase.pluralize
|
115
|
+
# children.delete child
|
116
|
+
# end
|
117
|
+
#
|
118
|
+
#
|
119
|
+
# end
|
120
|
+
|
121
|
+
|
122
|
+
end
|
@@ -0,0 +1,61 @@
|
|
1
|
+
require 'active_support/concern'
|
2
|
+
|
3
|
+
# TODO 05-05-2015 make Roleable work with other resource_class too
|
4
|
+
|
5
|
+
module Roleable
|
6
|
+
extend ActiveSupport::Concern
|
7
|
+
|
8
|
+
included do
|
9
|
+
# has_many :somthing
|
10
|
+
enum role: [:user, :vip, :account_admin, :admin]
|
11
|
+
attr_accessor :max_role
|
12
|
+
after_initialize :set_default_role, :if => :new_record?
|
13
|
+
|
14
|
+
validates_with RoleValidator
|
15
|
+
|
16
|
+
end
|
17
|
+
|
18
|
+
module ClassMethods
|
19
|
+
def policed_roles user
|
20
|
+
User.roles.keys.map {|role| [role.titleize,role] if User.roles[role] <= User.roles[user.role] }.compact
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
# role management
|
25
|
+
# ---------------
|
26
|
+
# enum listing possible roles
|
27
|
+
# max_role setting the model max role to that of the current user - you never can promote anyone above your own level
|
28
|
+
# set_default_role sets the role of a new user
|
29
|
+
#
|
30
|
+
|
31
|
+
class RoleValidator < ActiveModel::Validator
|
32
|
+
attr_accessor :user
|
33
|
+
def validate(record)
|
34
|
+
@user = record
|
35
|
+
Rails.logger.info ("roles: old %s new %s" % [ User.roles[record.previous_version.role], User.roles[record.role] ] ) rescue "no previous role"
|
36
|
+
if max_role_exhausted and old_role_less_than_new
|
37
|
+
record.errors[:role] << I18n.t('.assigned_role_not_allowed')
|
38
|
+
end
|
39
|
+
end
|
40
|
+
|
41
|
+
def old_role_less_than_new
|
42
|
+
User.roles[user.previous_version.role] < User.roles[user.role]
|
43
|
+
rescue
|
44
|
+
false
|
45
|
+
end
|
46
|
+
|
47
|
+
def max_role_exhausted
|
48
|
+
User.roles[user.role] > User.roles[user.max_role]
|
49
|
+
rescue
|
50
|
+
false
|
51
|
+
end
|
52
|
+
end
|
53
|
+
|
54
|
+
|
55
|
+
|
56
|
+
def set_default_role
|
57
|
+
self.role ||= :user
|
58
|
+
end
|
59
|
+
|
60
|
+
|
61
|
+
end
|
@@ -0,0 +1,58 @@
|
|
1
|
+
class AbstractResourcePolicy
|
2
|
+
class Scope
|
3
|
+
attr_reader :current_user, :scope
|
4
|
+
|
5
|
+
def initialize(user, scope)
|
6
|
+
@current_user = user
|
7
|
+
@scope = scope
|
8
|
+
end
|
9
|
+
|
10
|
+
def resolve
|
11
|
+
scope.all
|
12
|
+
end
|
13
|
+
end
|
14
|
+
|
15
|
+
attr_reader :current_user, :model
|
16
|
+
|
17
|
+
def initialize(current_user, model)
|
18
|
+
@current_user = current_user
|
19
|
+
@model = model
|
20
|
+
end
|
21
|
+
|
22
|
+
def index?
|
23
|
+
# @current_user.admin?
|
24
|
+
true
|
25
|
+
end
|
26
|
+
|
27
|
+
def new?
|
28
|
+
# @current_user.admin?
|
29
|
+
true
|
30
|
+
end
|
31
|
+
|
32
|
+
def edit?
|
33
|
+
# @current_user.admin?
|
34
|
+
true
|
35
|
+
end
|
36
|
+
|
37
|
+
def show?
|
38
|
+
# @current_user.admin? or @current_user == @user
|
39
|
+
true
|
40
|
+
end
|
41
|
+
|
42
|
+
def create?
|
43
|
+
# @current_user.admin?
|
44
|
+
true
|
45
|
+
end
|
46
|
+
|
47
|
+
def update?
|
48
|
+
# @current_user.admin?
|
49
|
+
true
|
50
|
+
end
|
51
|
+
|
52
|
+
def destroy?
|
53
|
+
# return false if @current_user == @user
|
54
|
+
# @current_user.admin?
|
55
|
+
true
|
56
|
+
end
|
57
|
+
|
58
|
+
end
|
data/app/views/.keep
ADDED
File without changes
|
@@ -0,0 +1,11 @@
|
|
1
|
+
<%- format = request.format.symbol.to_s %>
|
2
|
+
<hr/>
|
3
|
+
<h4>Explanation:</h4>
|
4
|
+
You 'hit' the '<%= params[:action]%>' action - and got the abstracted view template in response
|
5
|
+
(I'm guessing here: because the <%= params[:controller].pluralize.capitalize %>Controller is wired to inherit from AbstractedController)!
|
6
|
+
<h4>Errand</h4>
|
7
|
+
Add an <%= params[:action]%>.<%= format %>.<templating-language-suffix> file to the folder <%= Rails.root %>/app/views/<%= params[:controller].pluralize %>
|
8
|
+
<h4>Example</h4>
|
9
|
+
<pre>
|
10
|
+
<%= Rails.root %>/app/views/<%= params[:controller].pluralize %>/<strong><%= params[:action]%>.<%= format %>.haml</strong>
|
11
|
+
</pre>
|
@@ -0,0 +1 @@
|
|
1
|
+
= render 'layouts/messages'
|
@@ -0,0 +1,11 @@
|
|
1
|
+
- title = t( '%s.%s.title' % [@resource_class.table_name,params[:action]])
|
2
|
+
- content_for :title do
|
3
|
+
= title
|
4
|
+
|
5
|
+
- @disabled = false
|
6
|
+
|
7
|
+
%h3= title
|
8
|
+
= render 'form'
|
9
|
+
|
10
|
+
.right-align
|
11
|
+
= link_to t( @resource_class.table_name + '.actions.index'), resources_url, class: 'waves-effect waves-light btn'
|
@@ -0,0 +1 @@
|
|
1
|
+
<%= render partial: 'default' %>
|
@@ -0,0 +1,12 @@
|
|
1
|
+
- title = t( '%s.%s.title' % [@resource_class.table_name,params[:action]])
|
2
|
+
- content_for :title do
|
3
|
+
= title
|
4
|
+
|
5
|
+
- @disabled = false
|
6
|
+
|
7
|
+
%h3= title
|
8
|
+
= render 'form'
|
9
|
+
|
10
|
+
.row
|
11
|
+
.right-align
|
12
|
+
= link_to t( @resource_class.table_name + '.actions.index'), resources_url, class: 'waves-effect waves-light btn'
|
@@ -0,0 +1,13 @@
|
|
1
|
+
- content_for :title do
|
2
|
+
= t( @resource_class.table_name + '.show.title')
|
3
|
+
|
4
|
+
- @disabled = true
|
5
|
+
|
6
|
+
%h3= t( @resource_class.table_name + '.show.title')
|
7
|
+
|
8
|
+
= render 'form'
|
9
|
+
|
10
|
+
.row
|
11
|
+
.right-align
|
12
|
+
= link_to t( @resource_class.table_name + '.actions.edit'), edit_resource_url, class: 'waves-effect waves-light btn'
|
13
|
+
= link_to t( @resource_class.table_name + '.actions.index'), resources_url, class: 'waves-effect waves-light btn'
|
data/bin/rails
ADDED
@@ -0,0 +1,12 @@
|
|
1
|
+
#!/usr/bin/env ruby
|
2
|
+
# This command will automatically be run when you run "rails" with Rails 4 gems installed from the root of your application.
|
3
|
+
|
4
|
+
ENGINE_ROOT = File.expand_path('../..', __FILE__)
|
5
|
+
ENGINE_PATH = File.expand_path('../../lib/abstracted/engine', __FILE__)
|
6
|
+
|
7
|
+
# Set up gems listed in the Gemfile.
|
8
|
+
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
|
9
|
+
require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
|
10
|
+
|
11
|
+
require 'rails/all'
|
12
|
+
require 'rails/engine/commands'
|
@@ -0,0 +1,20 @@
|
|
1
|
+
en:
|
2
|
+
success:
|
3
|
+
created: '%{resource} was created successfully'
|
4
|
+
updated: '%{resource} was updated successfully'
|
5
|
+
deleted: '%{resource} was deleted successfully'
|
6
|
+
|
7
|
+
flash:
|
8
|
+
actions:
|
9
|
+
create:
|
10
|
+
notice: "%{resource_name} was successfully created."
|
11
|
+
update:
|
12
|
+
notice: "%{resource_name} was successfully updated."
|
13
|
+
destroy:
|
14
|
+
notice: "%{resource_name} was successfully destroyed."
|
15
|
+
alert: "%{resource_name} could not be destroyed."
|
16
|
+
alert_html: "<strong>OH NOES!</strong> You did it wrong!"
|
17
|
+
|
18
|
+
# posts:
|
19
|
+
# create:
|
20
|
+
# notice: "Your post was created and will be published soon"
|
data/config/routes.rb
ADDED
data/lib/abstracted.rb
ADDED
@@ -0,0 +1,19 @@
|
|
1
|
+
module Abstracted
|
2
|
+
class Engine < ::Rails::Engine
|
3
|
+
# config.autoload_paths << File.expand_path("../concerns", __FILE__)
|
4
|
+
|
5
|
+
config.generators do |g|
|
6
|
+
g.test_framework :rspec,
|
7
|
+
:fixture => false,
|
8
|
+
:fixtures => true,
|
9
|
+
:view_specs => false,
|
10
|
+
:helper_specs => false,
|
11
|
+
:routing_specs => false,
|
12
|
+
:controller_specs => true,
|
13
|
+
:request_specs => true
|
14
|
+
g.fixture_replacement :factory_girl, :dir => "spec/factories"
|
15
|
+
g.assets false
|
16
|
+
g.helper false
|
17
|
+
end
|
18
|
+
end
|
19
|
+
end
|
@@ -0,0 +1,7 @@
|
|
1
|
+
class AbstractedResponder < ActionController::Responder
|
2
|
+
include Responders::FlashResponder
|
3
|
+
include Responders::HttpCacheResponder
|
4
|
+
# Redirects resources to the collection path (index action) instead
|
5
|
+
# of the resource path (show action) for POST/PUT/DELETE requests.
|
6
|
+
include Responders::CollectionResponder
|
7
|
+
end
|