initial copy commit

This commit is contained in:
2017-12-21 11:36:52 +01:00
commit 659da24af3
135 changed files with 3288 additions and 0 deletions
+7
View File
@@ -0,0 +1,7 @@
.bundle/
log/*.log
pkg/
spec/dummy/db/*.sqlite3
spec/dummy/db/*.sqlite3-journal
spec/dummy/log/*.log
spec/dummy/tmp/
+1
View File
@@ -0,0 +1 @@
--require rails_helper
+32
View File
@@ -0,0 +1,32 @@
source 'https://rubygems.org'
# Declare your gem's dependencies in dunlop-ember.gemspec.
# Bundler will treat runtime dependencies like base dependencies, and
# development dependencies will be added by default to the :development group.
gemspec
gem 'coffee-rails'
gem 'kaminari'
group :development, :test do
gem 'rack-cors'
gem 'pry-rails'
gem 'pry-doc'
gem 'spring'
gem 'spring-commands-rspec'
gem 'rspec-rails'
gem 'cancancan'
gem 'slim-rails'
gem 'dunlop-core', github: 'companytools/dunlop-core', branch: 'master'
#gem 'dunlop-core', path: '~/development/rails/components/dunlop-core'
gem 'factory_girl_rails'
gem 'active_model_serializers'
gem 'database_cleaner'
end
# Declare any dependencies that are still in development here instead of in
# your gemspec. These might include edge Rails or gems from your path or
# Git. Remember to move these dependencies to your gemspec before releasing
# your gem to rubygems.org.
# To use a debugger
# gem 'byebug', group: [:development, :test]
+332
View File
@@ -0,0 +1,332 @@
GIT
remote: git://github.com/companytools/dunlop-core.git
revision: a7b86d3c17309d9de29bc2b4aa9a7dff842d619f
branch: master
specs:
dunlop-core (1.4.0)
cancancan
carrierwave
coffee-rails (~> 4.1)
devise
devise-token_authenticatable
exception_notification
facets
font-awesome-rails
js-routes
memoist
momentjs-rails
pickadate-rails (~> 3.5.5.0)
rails (>= 4.2.6)
ransack
record_collection (>= 0.10.4)
redcarpet
request_store
responders
sass-rails (>= 5.0.4)
simple_form
slim-rails
state_machines-activerecord
PATH
remote: .
specs:
dunlop-ember (0.1.0)
active_model_serializers
devise
rails (>= 4.2.0)
ransack
GEM
remote: https://rubygems.org/
specs:
actioncable (5.1.4)
actionpack (= 5.1.4)
nio4r (~> 2.0)
websocket-driver (~> 0.6.1)
actionmailer (5.1.4)
actionpack (= 5.1.4)
actionview (= 5.1.4)
activejob (= 5.1.4)
mail (~> 2.5, >= 2.5.4)
rails-dom-testing (~> 2.0)
actionpack (5.1.4)
actionview (= 5.1.4)
activesupport (= 5.1.4)
rack (~> 2.0)
rack-test (>= 0.6.3)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.0.2)
actionview (5.1.4)
activesupport (= 5.1.4)
builder (~> 3.1)
erubi (~> 1.4)
rails-dom-testing (~> 2.0)
rails-html-sanitizer (~> 1.0, >= 1.0.3)
active_attr (0.10.2)
activemodel (>= 3.0.2, < 5.2)
activesupport (>= 3.0.2, < 5.2)
active_model_serializers (0.10.6)
actionpack (>= 4.1, < 6)
activemodel (>= 4.1, < 6)
case_transform (>= 0.2)
jsonapi-renderer (>= 0.1.1.beta1, < 0.2)
activejob (5.1.4)
activesupport (= 5.1.4)
globalid (>= 0.3.6)
activemodel (5.1.4)
activesupport (= 5.1.4)
activerecord (5.1.4)
activemodel (= 5.1.4)
activesupport (= 5.1.4)
arel (~> 8.0)
activesupport (5.1.4)
concurrent-ruby (~> 1.0, >= 1.0.2)
i18n (~> 0.7)
minitest (~> 5.1)
tzinfo (~> 1.1)
addressable (2.5.2)
public_suffix (>= 2.0.2, < 4.0)
arel (8.0.0)
bcrypt (3.1.11)
builder (3.2.3)
cancancan (2.0.0)
capybara (2.15.2)
addressable
mini_mime (>= 0.1.3)
nokogiri (>= 1.3.3)
rack (>= 1.0.0)
rack-test (>= 0.5.4)
xpath (~> 2.0)
carrierwave (1.2.1)
activemodel (>= 4.0.0)
activesupport (>= 4.0.0)
mime-types (>= 1.16)
case_transform (0.2)
activesupport
coderay (1.1.2)
coffee-rails (4.2.2)
coffee-script (>= 2.2.0)
railties (>= 4.0.0)
coffee-script (2.4.1)
coffee-script-source
execjs
coffee-script-source (1.12.2)
concurrent-ruby (1.0.5)
crass (1.0.2)
database_cleaner (1.6.1)
devise (4.3.0)
bcrypt (~> 3.0)
orm_adapter (~> 0.1)
railties (>= 4.1.0, < 5.2)
responders
warden (~> 1.2.3)
devise-token_authenticatable (1.0.0)
devise (>= 4.0.0, < 4.4.0)
diff-lcs (1.3)
erubi (1.6.1)
exception_notification (4.2.2)
actionmailer (>= 4.0, < 6)
activesupport (>= 4.0, < 6)
execjs (2.7.0)
facets (3.1.0)
factory_girl (4.8.1)
activesupport (>= 3.0.0)
factory_girl_rails (4.8.0)
factory_girl (~> 4.8.0)
railties (>= 3.0.0)
ffi (1.9.18)
font-awesome-rails (4.7.0.2)
railties (>= 3.2, < 5.2)
globalid (0.4.0)
activesupport (>= 4.2.0)
i18n (0.8.6)
js-routes (1.4.2)
railties (>= 3.2)
sprockets-rails
jsonapi-renderer (0.1.3)
kaminari (1.0.1)
activesupport (>= 4.1.0)
kaminari-actionview (= 1.0.1)
kaminari-activerecord (= 1.0.1)
kaminari-core (= 1.0.1)
kaminari-actionview (1.0.1)
actionview
kaminari-core (= 1.0.1)
kaminari-activerecord (1.0.1)
activerecord
kaminari-core (= 1.0.1)
kaminari-core (1.0.1)
loofah (2.1.1)
crass (~> 1.0.2)
nokogiri (>= 1.5.9)
mail (2.6.6)
mime-types (>= 1.16, < 4)
memoist (0.16.0)
method_source (0.9.0)
mime-types (3.1)
mime-types-data (~> 3.2015)
mime-types-data (3.2016.0521)
mini_mime (0.1.4)
mini_portile2 (2.3.0)
minitest (5.10.3)
momentjs-rails (2.17.1)
railties (>= 3.1)
nio4r (2.1.0)
nokogiri (1.8.1)
mini_portile2 (~> 2.3.0)
orm_adapter (0.5.0)
pickadate-rails (3.5.5.0)
railties (>= 3.1.0)
polyamorous (1.3.1)
activerecord (>= 3.0)
pry (0.11.1)
coderay (~> 1.1.0)
method_source (~> 0.9.0)
pry-doc (0.11.1)
pry (~> 0.9)
yard (~> 0.9)
pry-rails (0.3.6)
pry (>= 0.10.4)
public_suffix (3.0.0)
rack (2.0.3)
rack-cors (1.0.1)
rack-test (0.7.0)
rack (>= 1.0, < 3)
rails (5.1.4)
actioncable (= 5.1.4)
actionmailer (= 5.1.4)
actionpack (= 5.1.4)
actionview (= 5.1.4)
activejob (= 5.1.4)
activemodel (= 5.1.4)
activerecord (= 5.1.4)
activesupport (= 5.1.4)
bundler (>= 1.3.0)
railties (= 5.1.4)
sprockets-rails (>= 2.0.0)
rails-dom-testing (2.0.3)
activesupport (>= 4.2.0)
nokogiri (>= 1.6)
rails-html-sanitizer (1.0.3)
loofah (~> 2.0)
railties (5.1.4)
actionpack (= 5.1.4)
activesupport (= 5.1.4)
method_source
rake (>= 0.8.7)
thor (>= 0.18.1, < 2.0)
rake (12.1.0)
ransack (1.8.3)
actionpack (>= 3.0)
activerecord (>= 3.0)
activesupport (>= 3.0)
i18n
polyamorous (~> 1.3)
rb-fsevent (0.10.2)
rb-inotify (0.9.10)
ffi (>= 0.5.0, < 2)
record_collection (0.10.4)
active_attr (>= 0.8)
activemodel (>= 4.1)
railties (>= 3.1)
redcarpet (3.4.0)
request_store (1.3.2)
responders (2.4.0)
actionpack (>= 4.2.0, < 5.3)
railties (>= 4.2.0, < 5.3)
rspec-core (3.6.0)
rspec-support (~> 3.6.0)
rspec-expectations (3.6.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.6.0)
rspec-mocks (3.6.0)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.6.0)
rspec-rails (3.6.1)
actionpack (>= 3.0)
activesupport (>= 3.0)
railties (>= 3.0)
rspec-core (~> 3.6.0)
rspec-expectations (~> 3.6.0)
rspec-mocks (~> 3.6.0)
rspec-support (~> 3.6.0)
rspec-support (3.6.0)
sass (3.5.3)
sass-listen (~> 4.0.0)
sass-listen (4.0.0)
rb-fsevent (~> 0.9, >= 0.9.4)
rb-inotify (~> 0.9, >= 0.9.7)
sass-rails (5.0.7)
railties (>= 4.0.0, < 6)
sass (~> 3.1)
sprockets (>= 2.8, < 4.0)
sprockets-rails (>= 2.0, < 4.0)
tilt (>= 1.1, < 3)
simple_form (3.5.0)
actionpack (> 4, < 5.2)
activemodel (> 4, < 5.2)
slim (3.0.8)
temple (>= 0.7.6, < 0.9)
tilt (>= 1.3.3, < 2.1)
slim-rails (3.1.2)
actionpack (>= 3.1)
railties (>= 3.1)
slim (~> 3.0)
spring (2.0.2)
activesupport (>= 4.2)
spring-commands-rspec (1.0.4)
spring (>= 0.9.1)
sprockets (3.7.1)
concurrent-ruby (~> 1.0)
rack (> 1, < 3)
sprockets-rails (3.2.1)
actionpack (>= 4.0)
activesupport (>= 4.0)
sprockets (>= 3.0.0)
sqlite3 (1.3.13)
state_machines (0.5.0)
state_machines-activemodel (0.5.0)
activemodel (>= 4.1, < 5.2)
state_machines (>= 0.5.0)
state_machines-activerecord (0.5.0)
activerecord (>= 4.1, < 5.2)
state_machines-activemodel (>= 0.5.0)
temple (0.8.0)
thor (0.20.0)
thread_safe (0.3.6)
tilt (2.0.8)
tzinfo (1.2.3)
thread_safe (~> 0.1)
warden (1.2.7)
rack (>= 1.0)
websocket-driver (0.6.5)
websocket-extensions (>= 0.1.0)
websocket-extensions (0.1.2)
xpath (2.1.0)
nokogiri (~> 1.3)
yard (0.9.9)
PLATFORMS
ruby
DEPENDENCIES
active_model_serializers
cancancan
capybara
coffee-rails
database_cleaner
dunlop-core!
dunlop-ember!
factory_girl_rails
kaminari
pry-doc
pry-rails
rack-cors
rspec-rails
slim-rails
spring
spring-commands-rspec
sqlite3
BUNDLED WITH
1.16.0
+1
View File
@@ -0,0 +1 @@
Copyright 2016 Companytools
+44
View File
@@ -0,0 +1,44 @@
# Dunlop::Ember
This gem adds some context and support for connection ember applications
## baic assumptions (for now (infrastructure is growing))
* The model structure is non namespaced with `api`
* The controllers have namespace `Api`, not versioned (controller level) api (yet):
```ruby
namespace :api, path: 'api/v1' do
# ...api controller definitions...
end
```
* The inheritance column for STI models is `sti_type` in stead of the
inconvenient chosen `type`:
```ruby
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
self.inheritance_column = :sti_type
end
```
* There is a UserSerializer in the main_app, can be same as `Api::User`
serializer `app/serializers/user_serializer.rb`:
```ruby
class UserSerializer < Api::UserSerializer
# attribute :email
# attribute :nickname
end
```
## Installation
Add this line to your application's Gemfile:
```ruby
gem 'dunlop-ember'
```
And then execute:
```bash
$ bundle
```
Add the engine to your routes file
```ruby
mount Dunlop::Ember::Engine => '/app'
```
+26
View File
@@ -0,0 +1,26 @@
begin
require 'bundler/setup'
rescue LoadError
puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
end
require 'rdoc/task'
RDoc::Task.new(:rdoc) do |rdoc|
rdoc.rdoc_dir = 'rdoc'
rdoc.title = 'Dunlop::Ember'
rdoc.options << '--line-numbers'
rdoc.rdoc_files.include('README.md')
rdoc.rdoc_files.include('lib/**/*.rb')
end
APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
load 'rails/tasks/engine.rake'
load 'rails/tasks/statistics.rake'
require 'bundler/gem_tasks'
@@ -0,0 +1,2 @@
//= link_directory ../javascripts/dunlop/ember .js
//= link_directory ../stylesheets/dunlop/ember .css
@@ -0,0 +1,13 @@
// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file. JavaScript code in this file should be added after the last require_* statement.
//
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require_tree .
@@ -0,0 +1,15 @@
/*
* This is a manifest file that'll be compiled into application.css, which will include all the files
* listed below.
*
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
*
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
* files in this directory. Styles in this file should be added after the last require_* statement.
* It is generally better to create a new file per style scope.
*
*= require_tree .
*= require_self
*/
@@ -0,0 +1,54 @@
module Dunlop
module Ember
class ApplicationController < ActionController::Base
protect_from_forgery with: :exception
before_action :authenticate_user_from_token!
before_action :authenticate_user!
def ember_path
app_globals = {}
if adapter_name = params[:adapter].to_s.scan(/\w+/).first.presence
app_index = Rails.root.join("public/adapters/#{adapter_name}/app/index.html")
return render text: 'unauthorized, no adapter engine', status: 403 unless adapter = Panda.adapters[adapter_name]
#app_globals = adapter.settings # load through request instead. More stable then changing environments
unless Rails.application.config.try(:loose_ember_app_authorization)
return render text: 'unauthorized, no adapter engine', status: 403 unless current_user.admin? or authorize!(:read, adapter.engine)
end
else
app_index = Rails.root.join('public/app/index.html')
end
Rails.logger.info "Loading ember app for path '#/#{params[:rest]}' adapter: '#{params[:adapter].presence || 'main_app'}'"
if app_index.exist?
index_html = app_index.read.to_s
app_globals[:flash] = flash.to_h if flash.present?
index_html.sub! 'app_globals={}', "app_globals=#{app_globals.to_json}" if app_globals.present?
render html: index_html.html_safe
else
render html: "App file <tt>#{app_index}</tt> not found".html_safe
end
end
rescue_from CanCan::AccessDenied do
if request.format.json?
head 403
else
render 'application/403', status: 403
end
end
private
def authenticate_user_from_token!
# https://romulomachado.github.io/2015/09/28/using-ember-simple-auth-with-devise.html
authenticate_with_http_token do |token, options|
user_email = options[:email].presence
user = user_email && User.find_by_email(user_email)
if user && Devise.secure_compare(user.authentication_token, token)
sign_in user, store: false
end
end
end
end
end
end
@@ -0,0 +1,27 @@
class Dunlop::Ember::SessionsController < Devise::SessionsController
#respond_to :json
skip_before_action :verify_authenticity_token, if: :json_request?, raise: false
#https://www.devmynd.com/blog/2014-7-rails-ember-js-with-the-ember-cli-redux-part-1-the-api-and-cms-with-ruby-on-rails/
def create
if json_request?
super do |user|
data = {
token: user.authentication_token,
email: user.email,
user_id: user.id
}
render json: data, status: 201 and return
end
else
super
end
end
protected
def json_request?
request.format.json?
end
end
@@ -0,0 +1,16 @@
module Dunlop::Ember
class UsersController < Dunlop::Ember::ApplicationController
def me
if respond_to?(:current_user) and current_user.present?
user = current_user
sign_out user # no more current_user, needed to allow sign_in using store: true to work (devise v4.3.0)
sign_in user, store: true # create session if not exist, only needed for hybrid rails/api integrations like ePOTS. Otherwise api only without store is sufficient
#sign_in current_user, store: true # create session if not exist, only needed for hybrid rails/api integrations like ePOTS. Otherwise api only without store is sufficient
#warden.set_user current_user, store: true
render json: current_user, serializer: UserSerializer
else
head 404
end
end
end
end
@@ -0,0 +1,6 @@
module Dunlop
module Ember
module ApplicationHelper
end
end
end
+6
View File
@@ -0,0 +1,6 @@
module Dunlop
module Ember
class ApplicationJob < ActiveJob::Base
end
end
end
@@ -0,0 +1,8 @@
module Dunlop
module Ember
class ApplicationMailer < ActionMailer::Base
default from: 'from@example.com'
layout 'mailer'
end
end
end
+51
View File
@@ -0,0 +1,51 @@
# Transform a nested tructure indicated by dots to a structure as used by the ActiveRecord includes statement
# - dslams
# - ppls.distribution_cables
# =>
# [:dslams, {ppls: :distribution_cables}]
class FlatKeys
class << self
def as_nested_structure(ary)
return ary unless ary.first.is_a?(String)
nested_keys, flat_keys = ary.partition{|spec| spec['.']}
result = flat_keys.map(&:to_sym)
if nested_keys.any?
obj = {}
nested_keys.map{ |key| key.split('.').map(&:to_sym) }.each do |parts|
traverse_nest_structure(parts, obj)
end
result.push obj
end
result
end
def traverse_nest_structure(parts, obj)
key = parts.shift
if parts.size == 1
case obj[key]
when nil then obj[key] = parts[0]
when Array then obj[key] |= [parts[0]]
when Hash
raise "Colliding keys for nesting of #{key} -> #{parts[0]}" unless obj[key].has_key?(parts[0])
else # expect symbol
obj[key] = Array.wrap(obj[key]).push parts[0] unless obj[key] == parts[0] # no duplicate
end
else # parts.size > 2
case obj[key]
when nil
obj[key] = {}
traverse_nest_structure(parts, obj[key])
when Array
raise "Cannot traverse #{key} -> #{parts.join('.')} because existing array value #{obj[key].inspect}"
when Hash
traverse_nest_structure(parts, obj[key])
else # expect symbol
raise "Cannot add deeper nesting for endpoing with different name #{key} -> #{obj[key]} => #{parts.join('.')}" unless obj[key] = parts[0] # same name, allows deeper nesting
obj[key] = {obj[key] => nil} # prepare for nesting
traverse_nest_structure(parts, obj[key])
end
end
end
end
end
@@ -0,0 +1,4 @@
h3
span Could not find
tt= '/app/index.html'
span file
@@ -0,0 +1,14 @@
<!DOCTYPE html>
<html>
<head>
<title>Dunlop ember</title>
<%= stylesheet_link_tag "dunlop/ember/application", media: "all" %>
<%= javascript_include_tag "dunlop/ember/application" %>
<%= csrf_meta_tags %>
</head>
<body>
<%= yield %>
</body>
</html>
Executable
+13
View File
@@ -0,0 +1,13 @@
#!/usr/bin/env ruby
# This command will automatically be run when you run "rails" with Rails gems
# installed from the root of your application.
ENGINE_ROOT = File.expand_path('../..', __FILE__)
ENGINE_PATH = File.expand_path('../../lib/dunlop/ember/engine', __FILE__)
# Set up gems listed in the Gemfile.
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
require 'rails/all'
require 'rails/engine/commands'
@@ -0,0 +1,7 @@
if defined?(ActiveModelSerializers)
ActiveModelSerializers.config.adapter = :json_api # Default: `:attributes`
#ActiveModelSerializers.config.key_transform = :unaltered # explicitly set because json api moves to dash
ActiveModelSerializers.config.jsonapi_pagination_links_enabled = false # manual meta setting
ActiveModelSerializers.config.jsonapi_namespace_separator = '/' # Default: `:attributes`
ActiveModelSerializers.config.jsonapi_resource_type = :singular
end
+8
View File
@@ -0,0 +1,8 @@
Dunlop::Ember::Engine.routes.draw do
get 'users/me'
devise_scope :user do
post 'users/sign_in', to: 'sessions#create'
end
root to: 'application#ember_path'
get '*rest', controller: 'application', action: 'ember_path'
end
+1
View File
@@ -0,0 +1 @@
Spring.application_root = './spec/dummy'
+29
View File
@@ -0,0 +1,29 @@
$:.push File.expand_path("../lib", __FILE__)
# Maintain your gem's version:
require "dunlop/ember/version"
# Describe your gem and declare its dependencies:
Gem::Specification.new do |s|
s.name = "dunlop-ember"
s.version = Dunlop::Ember::VERSION
s.authors = ["Companytools"]
s.email = ["develop@companytools.nl"]
s.homepage = "http://companytools.nl"
s.summary = "Summary of Dunlop::Ember."
s.description = "Description of Dunlop::Ember."
s.license = "COMPANYTOOLS"
s.files = Dir["{app,config,db,lib}/**/*", "LICENSE", "Rakefile", "README.md"]
s.test_files = Dir["spec/**/*"]
s.add_dependency "rails", ">= 4.2.0"
s.add_dependency "ransack"
s.add_dependency "devise"
s.add_dependency "active_model_serializers"
s.add_development_dependency "sqlite3"
s.add_development_dependency 'rspec-rails'
s.add_development_dependency 'capybara'
s.add_development_dependency 'factory_girl_rails'
end
+9
View File
@@ -0,0 +1,9 @@
require "dunlop/ember/engine"
require "dunlop/ember/cancan_safeguard"
require "dunlop/ember/api_base_controller"
module Dunlop
module Ember
# Your code goes here...
end
end
+252
View File
@@ -0,0 +1,252 @@
module Dunlop::Ember::ApiBaseController
extend ActiveSupport::Concern
included do
before_action :authenticate_user_from_token!
before_action :authenticate_user!
before_action :set_current_user
before_action :find_record, only: %i[show update destroy]
respond_to :json
rescue_from CanCan::AccessDenied do
render json: {errors: [{status: 403, detail: 'unauthorized'}]}, status: 403
end
end
def index
index_safeguard record_class
result = record_scope.search(query).result
result = result.includes(*FlatKeys.as_nested_structure(index_include_relations)) if index_include_relations.present?
result = result.uniq if params[:uniq].present?
if index_pagination?
paginated = result.page(params[:page]).per(params[:per_page])
render json: paginated, meta: {total_pages: paginated.total_pages, total_count: paginated.total_count}
else
render json: result
end
end
def show
show_safeguard @record
render json: @record
end
def create
@record ||= record_class.new(record_params)
create_safeguard @record
return if performed?
if @record.save
render json: @record
else
render json: {errors: @record.errors.map{|attr, errors| {attr => errors.to_s}}}, status: :unprocessable_entity
end
end
def update
update_safeguard @record
return if performed?
@record.update_attributes record_params
render json: @record
end
def destroy
destroy_safeguard @record
@record.destroy
head :no_content
end
private
# used to include relations on database lookup
# has form:
# ['comments.replies', 'authors.orginizations']
#
def include_relations
return [] unless includes = params[:include].presence
includes.split(',')
end
%i[index show].each do |action|
define_method "#{action}_include_relations" do
include_relations
end
end
def publish(event, data = {})
return
data = data.merge(event: event)
data[:client_id] = request.headers['HTTP_CLIENT_ID'] if request.present?
FayeRails.client(nil).publish('/activity', data)
end
def index_safeguard(model)
# can be overloaded
end
def show_safeguard(record)
# can be overloaded
record_safeguard(record)
end
def create_safeguard(record)
# can be overloaded
record_safeguard(record)
end
def update_safeguard(record)
# can be overloaded
record_safeguard(record)
end
def destroy_safeguard(record)
# can be overloaded
record_safeguard(record)
end
def record_safeguard(record)
# can be overloaded
return
render json: {}, status: :unauthorized unless authorized_ids(record).include?(current_user.id)
end
def authorized_ids(*)
# can be overloaded
[]
end
def authenticate_user_from_token!
# https://romulomachado.github.io/2015/09/28/using-ember-simple-auth-with-devise.html
authenticate_with_http_token do |token, options|
user_email = options[:email].presence
user = user_email && User.find_by_email(user_email)
if user && Devise.secure_compare(user.authentication_token, token)
sign_in user, store: false
end
end
end
public def record_class
deducted_class_name = controller_path.sub(/api\//,'').classify
deducted_class_name.safe_constantize || deducted_class_name.demodulize.constantize
end
# basic scope for find and index. Can be overloaded to add extra security restrictions
def record_scope
record_class.all
end
def find_record(options = {})
scope = record_scope
scope = scope.includes(*Array.wrap(options[:includes])) if options[:includes]
@record = scope.find(params[:id])
end
def record_params
#params.require(controller_path.sub(/^api\//, '').singularize).permit(*permitted_params)
params.require(controller_path.sub(/api\//, '').singularize).permit(*permitted_params)
end
def permitted_params
[]
end
# used for serialization
def serialize_options
return {} unless includes = params[:include].presence
{include: includes.split(',')}
end
# map action specific serialize options to general serialize options
%i[index show create update].each do |action|
define_method "#{action}_serialize_options" do
serialize_options
end
end
# /(_eq|_eq_any|_eq_all|_not_eq|_not_eq_any|_not_eq_all|_matches|_matches_any|_matches_all|
# _does_not_match|_does_not_match_any|_does_not_match_all|_lt|_lt_any|_lt_all|_lteq|_lteq_any|
# _lteq_all|_gt|_gt_any|_gt_all|_gteq|_gteq_any|_gteq_all|_in|_in_any|_in_all|_not_in|_not_in_any|
# _not_in_all|_cont|_cont_any|_cont_all|_i_cont|_i_cont_any|_i_cont_all|_not_cont|_not_cont_any|
# _not_cont_all|_i_not_cont|_i_not_cont_any|_i_not_cont_all|_start|_start_any|_start_all|_not_start|
# _not_start_any|_not_start_all|_end|_end_any|_end_all|_not_end|_not_end_any|_not_end_all|
# _true|_not_true|_false|_not_false|_present|_blank|_null|_not_null)$/
PREDICATE_END_MATCHER = Regexp.new("(_#{Ransack.predicates.keys.join('|_')})$")
#TODO: make me pretty, specs are in place
def query
mapped_query = {}
(params[:q] || {}).each do |key, value|
key = "#{key}_eq" unless %w[s sorts].include?(key) or record_class.try(:ransackable_scopes).try(:include?, key.to_sym) or key =~ PREDICATE_END_MATCHER # expect equality when no predicate is given
if key =~ /^type_/
# map type to sti_type
mapped_value = case value
when Array then value.map{|v| "#{record_class.name}::#{v.to_s.gsub('-', '_').classify}"}
else
"#{record_class.name}::#{value.to_s.gsub('-', '_').classify}"
end
mapped_query["sti_#{key}"] = mapped_value
else
mapped_query[key] = value
end
end
mapped_query
end
def _render_with_renderer_json(resource, options = {})
return resource.to_json if resource.is_a?(Hash)
return resource if resource.is_a?(String)
action_serialize_options_method = :"#{action_name}_serialize_options"
#action_serialize_options = respond_to?(action_serialize_options_method) ? __send__(action_serialize_options_method) : {}
action_serialize_options = __send__(action_serialize_options_method) rescue {}
action_serialize_options[:include] = options[:include] if options.has_key?(:include)
action_serialize_options[:meta] = options[:meta] if options.has_key?(:meta)
serializer_class = if options.has_key?(:serializer)
options.delete(:serializer)
elsif action_serialize_options[:serializer].present?
action_serialize_options[:serializer]
elsif resource.is_a?(ActiveRecord::Base)
#infer based on controller path replacing actual controller part with resouce part /workflow_step_definitions/:id/table
"#{self.class.name.deconstantize}::#{resource.class.name.demodulize}Serializer".constantize
elsif resource.is_a?(Array) and resource.first.is_a?(ActiveRecord::Base)
# infer based in first element of collection
"#{self.class.name.deconstantize}::#{resource.first.class.name.demodulize}Serializer".constantize
else
# infer based on controller path
"#{controller_path.underscore.classify}Serializer".constantize
end
serializer = if resource.respond_to?(:each)
ActiveModel::Serializer::CollectionSerializer.new(resource, action_serialize_options.merge(serializer: serializer_class)) #TODO: fix index includes
else
serializer_class.new(resource, action_serialize_options)
end
adapter = ActiveModelSerializers::Adapter::JsonApi.new(serializer, action_serialize_options)
res = {}
time = Benchmark.ms { res = adapter.as_json }
logger.info "Generated serialized output in #{time.round} ms"
#binding.pry
#return res
return res.is_a?(String) ? res : res.to_json
end
def has_permission_of_type(type, user = current_user)
Dunlop::Ability.has_permission_of_type(type, user)
end
def any_permission_starts_with(expression, user = current_user)
Dunlop::Ability.any_permission_starts_with(expression, user)
end
def index_pagination?
true
end
def set_current_user
request.env["exception_notifier.exception_data"] = {
current_user: current_user.try(:inspect)
}
User.current = current_user
end
end
+22
View File
@@ -0,0 +1,22 @@
module Dunlop::Ember::CanCanSafeguard
def index_safeguard(model)
authorize! :index, model
end
def show_safeguard(record)
authorize! :show, record
end
def create_safeguard(record)
authorize! :create, record
end
def update_safeguard(record)
authorize! :update, record
end
def destroy_safeguard(record)
authorize! :destroy, record
end
end
+14
View File
@@ -0,0 +1,14 @@
require 'devise'
require 'ransack'
require 'active_model_serializers'
module Dunlop
module Ember
class Engine < ::Rails::Engine
isolate_namespace Dunlop::Ember
config.generators do |g|
g.test_framework :rspec
end
end
end
end
+5
View File
@@ -0,0 +1,5 @@
module Dunlop
module Ember
VERSION = '0.1.0'
end
end
@@ -0,0 +1,8 @@
Description:
Explain the generator
Example:
rails generate install Thing
This will create:
what/will/it/create
@@ -0,0 +1,10 @@
class Dunlop::Ember::InstallGenerator < Rails::Generators::Base
source_root File.expand_path('../templates', __FILE__)
def add_initializers
directory 'initializers', 'config/initializers'
end
def upgrade_devise
gsub_file Rails.root.join('config/routes.rb'), /devise_for :users$/, "devise_for :users, controllers: {sessions: 'dunlop/ember/sessions'}"
end
end
@@ -0,0 +1,5 @@
ActiveModelSerializers.config.adapter = :json_api # Default: `:attributes`
#ActiveModelSerializers.config.key_transform = :unaltered # explicitly set because json api moves to dash
ActiveModelSerializers.config.jsonapi_pagination_links_enabled = false # manual meta setting
ActiveModelSerializers.config.jsonapi_namespace_separator = '/' # Default: `:attributes`
ActiveModelSerializers.config.jsonapi_resource_type = :singular
@@ -0,0 +1,8 @@
api_mime_types = %W[
application/vnd.api+json
text/x-json
application/json
]
Mime::Type.unregister :json
Mime::Type.register 'application/json', :json, api_mime_types
+4
View File
@@ -0,0 +1,4 @@
# desc "Explaining what the task does"
# task :dunlop_ember do
# # Task goes here
# end
@@ -0,0 +1,110 @@
require 'rails_helper'
RSpec.describe Api::PostsController, type: :controller do
describe "index" do
describe 'unauthorized' do
it 'redirects to login page' do
get :index
response.redirect_url.should end_with('/users/sign_in')
end
end
describe 'authorized' do
before { sign_in create :user }
it "no default include, default pagination" do
post1 = create :post, title: 'post-1', body: 'post-body-1'
comment = create :comment, post: post1
post2 = create :post, title: 'post-2', body: 'post-body-2'
get :index
assert_json(
data: [
{
id: post1.id.to_s,
type: "post",
attributes: {"title"=>"post-1", "body"=>"post-body-1"},
relationships: {
comments: {data: [{id: comment.id.to_s , type: "comment" }]}
}
},
{
id: post2.id.to_s,
type: "post",
attributes: {"title"=>"post-2", "body"=>"post-body-2"},
relationships: {
comments: {data: []}
}
},
],
meta: {"total-pages"=>1, "total-count"=>2}
)
end
it "does not paginate when index_pagination? is false" do
expect( subject ).to receive(:index_pagination?).and_return false
post1 = create :post, title: 'post-1', body: 'post-body-1'
comment = create :comment, post: post1
post2 = create :post, title: 'post-2', body: 'post-body-2'
get :index
assert_json(
data: [
{
id: post1.id.to_s,
type: "post",
attributes: {"title"=>"post-1", "body"=>"post-body-1"},
relationships: {
comments: {data: [{id: comment.id.to_s , type: "comment" }]}
}
},
{
id: post2.id.to_s,
type: "post",
attributes: {"title"=>"post-2", "body"=>"post-body-2"},
relationships: {
comments: {data: []}
}
},
]
)
end
it "includes associations if configured" do
expect( subject ).to receive(:index_serialize_options).and_return(include: 'comments')
post1 = create :post, title: 'post-1', body: 'post-body-1'
comment = create :comment, post: post1, body: 'post-1-comment-1'
post2 = create :post, title: 'post-2', body: 'post-body-2'
get :index
assert_json(
data: [
{
id: post1.id.to_s,
type: "post",
attributes: {"title"=>"post-1", "body"=>"post-body-1"},
relationships: {
comments: {data: [{id: comment.id.to_s , type: "comment" }]}
}
},
{
id: post2.id.to_s,
type: "post",
attributes: {"title"=>"post-2", "body"=>"post-body-2"},
relationships: {
comments: {data: []}
}
},
],
included: [
{
id: comment.id.to_s,
type: "comment",
attributes: {body: "post-1-comment-1"},
relationships: {
post: {data: {id: post1.id.to_s, type: "posts"}}
}
}
],
meta: {"total-pages"=>1, "total-count"=>2}
)
end
end
end
end
@@ -0,0 +1,42 @@
require 'rails_helper'
RSpec.describe Api::PostsController, type: :controller do
describe "update" do
describe 'unauthorized' do
it 'redirects to login page' do
patch :update, params: {id: 9}
response.redirect_url.should end_with('/users/sign_in')
end
end
describe 'authorized' do
before { sign_in create :user }
it "includes associations if configured" do
expect( subject ).to receive(:update_serialize_options).and_return(include: 'comments')
post1 = create :post, title: 'post-1', body: 'post-body-1'
comment = create :comment, post: post1, body: 'post-1-comment-1'
patch :update, params: {id: post1.id, post: {title: 'post-1-updated', body: 'post-body-1-updated'}}
assert_json(
data: {
id: post1.id.to_s,
type: "post",
attributes: {"title"=>"post-1", "body"=>"post-body-1-updated"}, # title not permitted, could be boolean admin
relationships: {
comments: {data: [{id: comment.id.to_s , type: "comment" }]}
}
},
included: [
{
id: comment.id.to_s,
type: "comment",
attributes: {body: "post-1-comment-1"},
relationships: {
post: {data: {id: post1.id.to_s, type: "posts"}}
}
}
]
)
end
end
end
end
+6
View File
@@ -0,0 +1,6 @@
# Add your own tasks in files placed in lib/tasks ending in .rake,
# for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
require_relative 'config/application'
Rails.application.load_tasks
+5
View File
@@ -0,0 +1,5 @@
//= link_tree ../images
//= link_directory ../javascripts .js
//= link_directory ../stylesheets .css
//= link dunlop_ember_manifest.js
View File
@@ -0,0 +1,13 @@
// This is a manifest file that'll be compiled into application.js, which will include all the files
// listed below.
//
// Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts,
// or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path.
//
// It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the
// compiled file. JavaScript code in this file should be added after the last require_* statement.
//
// Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details
// about supported directives.
//
//= require_tree .
@@ -0,0 +1,13 @@
// Action Cable provides the framework to deal with WebSockets in Rails.
// You can generate new channels where WebSocket features live using the rails generate channel command.
//
//= require action_cable
//= require_self
//= require_tree ./channels
(function() {
this.App || (this.App = {});
App.cable = ActionCable.createConsumer();
}).call(this);
@@ -0,0 +1,3 @@
# Place all the behaviors and hooks related to the matching controller here.
# All this logic will automatically be available in application.js.
# You can use CoffeeScript in this file: http://coffeescript.org/
@@ -0,0 +1,15 @@
/*
* This is a manifest file that'll be compiled into application.css, which will include all the files
* listed below.
*
* Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets,
* or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path.
*
* You're free to add application-wide styles to this file and they'll appear at the bottom of the
* compiled file so the styles you add here take precedence over styles defined in any other CSS/SCSS
* files in this directory. Styles in this file should be added after the last require_* statement.
* It is generally better to create a new file per style scope.
*
*= require_tree .
*= require_self
*/
@@ -0,0 +1,4 @@
module ApplicationCable
class Channel < ActionCable::Channel::Base
end
end
@@ -0,0 +1,4 @@
module ApplicationCable
class Connection < ActionCable::Connection::Base
end
end
@@ -0,0 +1,5 @@
module Api
class BaseController < ActionController::Base
include Dunlop::Ember::ApiBaseController
end
end
@@ -0,0 +1,7 @@
module Api
class PostsController < Api::BaseController
def permitted_params
[:body] # title not permitted
end
end
end
@@ -0,0 +1,32 @@
class ApplicationController < ActionController::Base
# Prevent CSRF attacks by raising an exception.
# For APIs, you may want to use :null_session instead.
protect_from_forgery with: :exception
before_action :authenticate_user!
#http://rails-bestpractices.com/posts/2010/08/23/fetch-current-user-in-models
before_action :set_current_user
rescue_from CanCan::AccessDenied do
render 'application/403', status: 403
end
private
def set_current_user
request.env["exception_notifier.exception_data"] = {
current_user: current_user.try(:inspect)
}
User.current = current_user
end
# Return an array of ids given as a param or nil if nothing is supplied
def ids_param
return nil unless ids = params[:ids].presence
@ids_param ||= (ids.is_a?(String) ? ids.split(RecordCollection.ids_separator) : Array.wrap(ids))
end
helper_method :ids_param
end
@@ -0,0 +1,58 @@
class CommentsController < ApplicationController
before_action :set_comment, only: [:show, :edit, :update, :destroy]
# GET /comments
def index
@comments = Comment.all
end
# GET /comments/1
def show
end
# GET /comments/new
def new
@comment = Comment.new
end
# GET /comments/1/edit
def edit
end
# POST /comments
def create
@comment = Comment.new(comment_params)
if @comment.save
redirect_to @comment, notice: 'Comment was successfully created.'
else
render :new
end
end
# PATCH/PUT /comments/1
def update
if @comment.update(comment_params)
redirect_to @comment, notice: 'Comment was successfully updated.'
else
render :edit
end
end
# DELETE /comments/1
def destroy
@comment.destroy
redirect_to comments_url, notice: 'Comment was successfully destroyed.'
end
private
# Use callbacks to share common setup or constraints between actions.
def set_comment
@comment = Comment.find(params[:id])
end
# Only allow a trusted parameter "white list" through.
def comment_params
params.require(:comment).permit(:user_id, :post_id, :body)
end
end
@@ -0,0 +1,58 @@
class PostsController < ApplicationController
before_action :set_post, only: [:show, :edit, :update, :destroy]
# GET /posts
def index
@posts = Post.all
end
# GET /posts/1
def show
end
# GET /posts/new
def new
@post = Post.new
end
# GET /posts/1/edit
def edit
end
# POST /posts
def create
@post = Post.new(post_params)
if @post.save
redirect_to @post, notice: 'Post was successfully created.'
else
render :new
end
end
# PATCH/PUT /posts/1
def update
if @post.update(post_params)
redirect_to @post, notice: 'Post was successfully updated.'
else
render :edit
end
end
# DELETE /posts/1
def destroy
@post.destroy
redirect_to posts_url, notice: 'Post was successfully destroyed.'
end
private
# Use callbacks to share common setup or constraints between actions.
def set_post
@post = Post.find(params[:id])
end
# Only allow a trusted parameter "white list" through.
def post_params
params.require(:post).permit(:title, :body)
end
end
@@ -0,0 +1,2 @@
module ApplicationHelper
end
@@ -0,0 +1,2 @@
module CommentsHelper
end
+2
View File
@@ -0,0 +1,2 @@
module PostsHelper
end
+2
View File
@@ -0,0 +1,2 @@
class ApplicationJob < ActiveJob::Base
end
@@ -0,0 +1,4 @@
class ApplicationMailer < ActionMailer::Base
default from: 'from@example.com'
layout 'mailer'
end
+7
View File
@@ -0,0 +1,7 @@
class Ability
include Dunlop::Ability
def setup_abilities
setup_dunlop_abilities
end
end
@@ -0,0 +1,18 @@
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
self.inheritance_column = :sti_type
if Rails::VERSION::MAJOR < 5
def saved_changes
changes
end
end
class << self
def truncate
#connection_pool.with_connection { |c| c.truncate table_name }
delete_all
end
end
end
+3
View File
@@ -0,0 +1,3 @@
class Comment < ApplicationRecord
belongs_to :post
end
+3
View File
@@ -0,0 +1,3 @@
class ExecutionBatch < ApplicationRecord
include Dunlop::ExecutionBatchModel
end
+3
View File
@@ -0,0 +1,3 @@
class Post < ApplicationRecord
has_many :comments
end
+11
View File
@@ -0,0 +1,11 @@
class User < ApplicationRecord
include Dunlop::UserModel
# Include default devise modules. Others available are:
# :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, #:token_authenticatable, #:registerable,
:recoverable, :rememberable, :trackable, :validatable
# To be overridden, with application logic
scope :active, ->{ all }
end
@@ -0,0 +1,4 @@
class Api::CommentSerializer < ActiveModel::Serializer
attribute :body
belongs_to :post
end
@@ -0,0 +1,5 @@
class Api::PostSerializer < ActiveModel::Serializer
attribute :title
attribute :body
has_many :comments
end
@@ -0,0 +1,18 @@
= form_for @comment do |f|
- if @comment.errors.any?
#error_explanation
h2 = "#{pluralize(@comment.errors.count, "error")} prohibited this comment from being saved:"
ul
- @comment.errors.full_messages.each do |message|
li = message
.field
= f.label :user_id
= f.number_field :user_id
.field
= f.label :post_id
= f.number_field :post_id
.field
= f.label :body
= f.text_area :body
.actions = f.submit
@@ -0,0 +1,8 @@
h1 Editing comment
== render 'form'
= link_to 'Show', @comment
' |
= link_to 'Back', comments_path
@@ -0,0 +1,25 @@
h1 Listing comments
table
thead
tr
th User
th Post
th Body
th
th
th
tbody
- @comments.each do |comment|
tr
td = comment.user_id
td = comment.post_id
td = comment.body
td = link_to 'Show', comment
td = link_to 'Edit', edit_comment_path(comment)
td = link_to 'Destroy', comment, data: { confirm: 'Are you sure?' }, method: :delete
br
= link_to 'New Comment', new_comment_path
@@ -0,0 +1,5 @@
h1 New comment
== render 'form'
= link_to 'Back', comments_path
@@ -0,0 +1,15 @@
p#notice = notice
p
strong User:
= @comment.user_id
p
strong Post:
= @comment.post_id
p
strong Body:
= @comment.body
= link_to 'Edit', edit_comment_path(@comment)
' |
= link_to 'Back', comments_path
@@ -0,0 +1,5 @@
- flash.each do |name, msg|
- if msg.is_a?(String)
div.alert-box.round class="#{name.to_s == 'notice' ? 'success' : 'alert'}" data-alert=""
= content_tag :div, msg
a.close href="#" &times;
@@ -0,0 +1,5 @@
nav.top-bar data-topbar=true
ul.title-area
li.name= link_to application_name, main_app.root_path
li.toggle-topbar.menu-icon: a href="#": span Menu
.top-bar-section= render 'layouts/navigation_links'
@@ -0,0 +1,39 @@
- if signed_in?
ul.right
li class=active_class('dunlop#changelog')
= link_to Rails.application.config.git_version, dunlop.changelog_path, title: 'Current version, click for changelog'
li class=active_class('dunlop/users#profile', 'dunlop/users#edit_profile') = link_to current_user.email.to_s.sub(/\@.*/, ''), dunlop.profile_users_path
li= link_to 'Sign out', main_app.destroy_user_session_path, method: :delete
ul.left
- if can? :index, WorkflowInstance
li.has-dropdown class=active_class('workflow_instance')
= link_to WorkflowInstance.model_name.human_plural, '#'
ul.dropdown
- WorkflowInstance.scenario_classes.each do |scenario|
- if can? :read, scenario
li class=active_class("workflow_instance/#{scenario.process_name.pluralize}") = link_to scenario.model_name.human_plural, [main_app, scenario]
- if can? :index, WorkflowInstanceBatch
li.has-dropdown class=active_class('workflow_instance_batch')
= link_to WorkflowInstanceBatch.model_name.human_plural, '#'
ul.dropdown
- WorkflowInstance.scenario_classes.each do |scenario|
- if can? :read, scenario.batch_class
li class=active_class("workflow_instance_batch/#{scenario.batch_class.process_name.pluralize}") = link_to scenario.batch_class.model_name.human_plural, [main_app, scenario.batch_class]
/- if can? :index, SourceFile or can? :index, TargetFile
li.has-dropdown class=active_class('dunlop/source_files', 'dunlop/target_files')
= link_to 'Files', '#'
ul.dropdown
- if can? :index, SourceFile
li class=active_class('dunlop/source_files') = link_to SourceFile.model_name.human_plural, dunlop.source_files_path
- if can? :index, TargetFile
li class=active_class('dunlop/target_files') = link_to TargetFile.model_name.human_plural, dunlop.target_files_path
- if can? :index, User
li.has-dropdown class=active_class("dunlop/users", except: /profile$/)
= link_to 'Admin', '#'
ul.dropdown
li class=active_class('dunlop/users', except: /profile$/) = link_to User.model_name.human_plural, dunlop.users_path
/li{ class: active_class('manual') }= link_to 'Manual', manual_root_path
- else
ul.right
li= link_to 'Sign In', main_app.new_user_session_path
@@ -0,0 +1,27 @@
doctype html
html
head
meta name="viewport" content="width=device-width, initial-scale=1.0"
title= content_for?(:title) ? yield(:title) : application_name
meta name="description" content="#{content_for?(:description) ? yield(:description) : 'Migration Dashboard'}"
= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true
= javascript_include_tag 'vendor/modernizr'
= javascript_include_tag 'application', 'data-turbolinks-track' => true
= csrf_meta_tags
body class=body_classes
#workflow-step-modal.reveal-modal data-reveal=""
.content
a.close-reveal-modal ×
header= render 'layouts/navigation'
main role="main"
.environment-ribbon class=Rails.env
span= Rails.env
= render 'layouts/messages'
= yield
footer
.right
Powered by
= link_to 'FourStack B.V.', 'http://fourstack.nl/', target: :_blank
#display-badge-info-popup.reveal-modal data-reveal=""
.display-badge-info-content
a.close-reveal-modal x
@@ -0,0 +1,13 @@
<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<style>
/* Email styles need to be inline */
</style>
</head>
<body>
<%= yield %>
</body>
</html>
@@ -0,0 +1 @@
<%= yield %>
@@ -0,0 +1,15 @@
= form_for @post do |f|
- if @post.errors.any?
#error_explanation
h2 = "#{pluralize(@post.errors.count, "error")} prohibited this post from being saved:"
ul
- @post.errors.full_messages.each do |message|
li = message
.field
= f.label :title
= f.text_field :title
.field
= f.label :body
= f.text_area :body
.actions = f.submit
@@ -0,0 +1,8 @@
h1 Editing post
== render 'form'
= link_to 'Show', @post
' |
= link_to 'Back', posts_path
@@ -0,0 +1,23 @@
h1 Listing posts
table
thead
tr
th Title
th Body
th
th
th
tbody
- @posts.each do |post|
tr
td = post.title
td = post.body
td = link_to 'Show', post
td = link_to 'Edit', edit_post_path(post)
td = link_to 'Destroy', post, data: { confirm: 'Are you sure?' }, method: :delete
br
= link_to 'New Post', new_post_path
+5
View File
@@ -0,0 +1,5 @@
h1 New post
== render 'form'
= link_to 'Back', posts_path
+12
View File
@@ -0,0 +1,12 @@
p#notice = notice
p
strong Title:
= @post.title
p
strong Body:
= @post.body
= link_to 'Edit', edit_post_path(@post)
' |
= link_to 'Back', posts_path
+3
View File
@@ -0,0 +1,3 @@
#!/usr/bin/env ruby
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
load Gem.bin_path('bundler', 'bundle')
+4
View File
@@ -0,0 +1,4 @@
#!/usr/bin/env ruby
APP_PATH = File.expand_path('../config/application', __dir__)
require_relative '../config/boot'
require 'rails/commands'
+4
View File
@@ -0,0 +1,4 @@
#!/usr/bin/env ruby
require_relative '../config/boot'
require 'rake'
Rake.application.run
+34
View File
@@ -0,0 +1,34 @@
#!/usr/bin/env ruby
require 'pathname'
require 'fileutils'
include FileUtils
# path to your application root.
APP_ROOT = Pathname.new File.expand_path('../../', __FILE__)
def system!(*args)
system(*args) || abort("\n== Command #{args} failed ==")
end
chdir APP_ROOT do
# This script is a starting point to setup your application.
# Add necessary setup steps to this file.
puts '== Installing dependencies =='
system! 'gem install bundler --conservative'
system('bundle check') || system!('bundle install')
# puts "\n== Copying sample files =="
# unless File.exist?('config/database.yml')
# cp 'config/database.yml.sample', 'config/database.yml'
# end
puts "\n== Preparing database =="
system! 'bin/rails db:setup'
puts "\n== Removing old logs and tempfiles =="
system! 'bin/rails log:clear tmp:clear'
puts "\n== Restarting application server =="
system! 'bin/rails restart'
end
+29
View File
@@ -0,0 +1,29 @@
#!/usr/bin/env ruby
require 'pathname'
require 'fileutils'
include FileUtils
# path to your application root.
APP_ROOT = Pathname.new File.expand_path('../../', __FILE__)
def system!(*args)
system(*args) || abort("\n== Command #{args} failed ==")
end
chdir APP_ROOT do
# This script is a way to update your development environment automatically.
# Add necessary update steps to this file.
puts '== Installing dependencies =='
system! 'gem install bundler --conservative'
system('bundle check') || system!('bundle install')
puts "\n== Updating database =="
system! 'bin/rails db:migrate'
puts "\n== Removing old logs and tempfiles =="
system! 'bin/rails log:clear tmp:clear'
puts "\n== Restarting application server =="
system! 'bin/rails restart'
end
+5
View File
@@ -0,0 +1,5 @@
# This file is used by Rack-based servers to start the application.
require_relative 'config/environment'
run Rails.application
+37
View File
@@ -0,0 +1,37 @@
require_relative 'boot'
# Pick the frameworks you want:
require "active_record/railtie"
require "action_controller/railtie"
require "action_view/railtie"
require "action_mailer/railtie"
require "active_job/railtie"
require "action_cable/engine"
# require "rails/test_unit/railtie"
require "sprockets/railtie"
Bundler.require(*Rails.groups)
require "dunlop/ember"
module Dummy
class Application < Rails::Application
config.application_name = "Dummy"
config.git_version = Rails.env
config.git_version = File.read('REVISION').strip if File.exists?('REVISION')
config.git_version = File.read('OFFLINE_REVISION').strip if File.exists?('OFFLINE_REVISION')
config.load_defaults 5.1
config.middleware.insert_before 0, Rack::Cors do
allow do
origins '*'
resource '*', headers: :any, methods: [:get, :post, :options, :delete, :put, :patch]
end
end
# Settings in config/environments/* take precedence over those specified here.
# Application configuration should go into files in config/initializers
# -- all .rb files in that directory are automatically loaded.
end
end
+5
View File
@@ -0,0 +1,5 @@
# Set up gems listed in the Gemfile.
ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../../Gemfile', __dir__)
require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE'])
$LOAD_PATH.unshift File.expand_path('../../../lib', __dir__)
+9
View File
@@ -0,0 +1,9 @@
development:
adapter: async
test:
adapter: async
production:
adapter: redis
url: redis://localhost:6379/1
+25
View File
@@ -0,0 +1,25 @@
# SQLite version 3.x
# gem install sqlite3
#
# Ensure the SQLite 3 gem is defined in your Gemfile
# gem 'sqlite3'
#
default: &default
adapter: sqlite3
pool: 5
timeout: 5000
development:
<<: *default
database: db/development.sqlite3
# Warning: The database defined as "test" will be erased and
# re-generated from your development database when you run "rake".
# Do not set this db to the same as development or production.
test:
<<: *default
database: db/test.sqlite3
production:
<<: *default
database: db/production.sqlite3
+5
View File
@@ -0,0 +1,5 @@
# Load the Rails application.
require_relative 'application'
# Initialize the Rails application.
Rails.application.initialize!
@@ -0,0 +1,58 @@
Rails.application.configure do
config.time_zone = 'Moscow'
config.git_version = 'develop'
# Settings specified here will take precedence over those in config/application.rb.
# In the development environment your application's code is reloaded on
# every request. This slows down response time but is perfect for development
# since you don't have to restart the web server when you make code changes.
config.cache_classes = false
# Do not eager load code on boot.
config.eager_load = false
# Show full error reports.
config.consider_all_requests_local = true
# Enable/disable caching. By default caching is disabled.
if Rails.root.join('tmp/caching-dev.txt').exist?
config.action_controller.perform_caching = true
config.cache_store = :memory_store
config.public_file_server.headers = {
'Cache-Control' => 'public, max-age=172800'
}
else
config.action_controller.perform_caching = false
config.cache_store = :null_store
end
# Don't care if the mailer can't send.
config.action_mailer.raise_delivery_errors = false
config.action_mailer.perform_caching = false
# Print deprecation notices to the Rails logger.
config.active_support.deprecation = :log
# Raise an error on page load if there are pending migrations.
config.active_record.migration_error = :page_load
# Debug mode disables concatenation and preprocessing of assets.
# This option may cause significant delays in view rendering with a large
# number of complex assets.
config.assets.debug = true
# Suppress logger output for asset requests.
config.assets.quiet = true
# Raises error for missing translations
# config.action_view.raise_on_missing_translations = true
# Use an evented file watcher to asynchronously detect changes in source code,
# routes, locales, etc. This feature depends on the listen gem.
# config.file_watcher = ActiveSupport::EventedFileUpdateChecker
end
@@ -0,0 +1,86 @@
Rails.application.configure do
# Settings specified here will take precedence over those in config/application.rb.
# Code is not reloaded between requests.
config.cache_classes = true
# Eager load code on boot. This eager loads most of Rails and
# your application in memory, allowing both threaded web servers
# and those relying on copy on write to perform better.
# Rake tasks automatically ignore this option for performance.
config.eager_load = true
# Full error reports are disabled and caching is turned on.
config.consider_all_requests_local = false
config.action_controller.perform_caching = true
# Disable serving static files from the `/public` folder by default since
# Apache or NGINX already handles this.
config.public_file_server.enabled = ENV['RAILS_SERVE_STATIC_FILES'].present?
# Compress JavaScripts and CSS.
config.assets.js_compressor = :uglifier
# config.assets.css_compressor = :sass
# Do not fallback to assets pipeline if a precompiled asset is missed.
config.assets.compile = false
# `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb
# Enable serving of images, stylesheets, and JavaScripts from an asset server.
# config.action_controller.asset_host = 'http://assets.example.com'
# Specifies the header that your server uses for sending files.
# config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache
# config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX
# Mount Action Cable outside main process or domain
# config.action_cable.mount_path = nil
# config.action_cable.url = 'wss://example.com/cable'
# config.action_cable.allowed_request_origins = [ 'http://example.com', /http:\/\/example.*/ ]
# Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
# config.force_ssl = true
# Use the lowest log level to ensure availability of diagnostic information
# when problems arise.
config.log_level = :debug
# Prepend all log lines with the following tags.
config.log_tags = [ :request_id ]
# Use a different cache store in production.
# config.cache_store = :mem_cache_store
# Use a real queuing backend for Active Job (and separate queues per environment)
# config.active_job.queue_adapter = :resque
# config.active_job.queue_name_prefix = "dummy_#{Rails.env}"
config.action_mailer.perform_caching = false
# Ignore bad email addresses and do not raise email delivery errors.
# Set this to true and configure the email server for immediate delivery to raise delivery errors.
# config.action_mailer.raise_delivery_errors = false
# Enable locale fallbacks for I18n (makes lookups for any locale fall back to
# the I18n.default_locale when a translation cannot be found).
config.i18n.fallbacks = true
# Send deprecation notices to registered listeners.
config.active_support.deprecation = :notify
# Use default logging formatter so that PID and timestamp are not suppressed.
config.log_formatter = ::Logger::Formatter.new
# Use a different logger for distributed setups.
# require 'syslog/logger'
# config.logger = ActiveSupport::TaggedLogging.new(Syslog::Logger.new 'app-name')
if ENV["RAILS_LOG_TO_STDOUT"].present?
logger = ActiveSupport::Logger.new(STDOUT)
logger.formatter = config.log_formatter
config.logger = ActiveSupport::TaggedLogging.new(logger)
end
# Do not dump schema after migrations.
config.active_record.dump_schema_after_migration = false
end
+46
View File
@@ -0,0 +1,46 @@
Rails.application.configure do
config.time_zone = 'Moscow'
config.git_version = 'test'
# Settings specified here will take precedence over those in config/application.rb.
# The test environment is used exclusively to run your application's
# test suite. You never need to work with it otherwise. Remember that
# your test database is "scratch space" for the test suite and is wiped
# and recreated between test runs. Don't rely on the data there!
config.cache_classes = true
# Do not eager load code on boot. This avoids loading your whole application
# just for the purpose of running a single test. If you are using a tool that
# preloads Rails for running tests, you may have to set it to true.
config.eager_load = false
# Configure public file server for tests with Cache-Control for performance.
config.public_file_server.enabled = true
config.public_file_server.headers = {
'Cache-Control' => 'public, max-age=3600'
}
# Show full error reports and disable caching.
config.consider_all_requests_local = true
config.action_controller.perform_caching = false
# Raise exceptions instead of rendering exception templates.
config.action_dispatch.show_exceptions = false
# Disable request forgery protection in test environment.
config.action_controller.allow_forgery_protection = false
config.action_mailer.perform_caching = false
# Tell Action Mailer not to deliver emails to the real world.
# The :test delivery method accumulates sent emails in the
# ActionMailer::Base.deliveries array.
config.action_mailer.delivery_method = :test
# Print deprecation notices to the stderr.
config.active_support.deprecation = :stderr
# Raises error for missing translations
# config.action_view.raise_on_missing_translations = true
end
@@ -0,0 +1,6 @@
# Be sure to restart your server when you modify this file.
# ApplicationController.renderer.defaults.merge!(
# http_host: 'example.org',
# https: false
# )
+11
View File
@@ -0,0 +1,11 @@
# Be sure to restart your server when you modify this file.
# Version of your assets, change this if you want to expire all your assets.
Rails.application.config.assets.version = '1.0'
# Add additional assets to the asset load path
# Rails.application.config.assets.paths << Emoji.images_path
# Precompile additional assets.
# application.js, application.css, and all non-JS/CSS in app/assets folder are already added.
# Rails.application.config.assets.precompile += %w( search.js )
@@ -0,0 +1,7 @@
# Be sure to restart your server when you modify this file.
# You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces.
# Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ }
# You can also remove all the silencers if you're trying to debug a problem that might stem from framework code.
# Rails.backtrace_cleaner.remove_silencers!

Some files were not shown because too many files have changed in this diff Show More