introspective_grape 0.5.7 → 0.7.0

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 (70) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +85 -84
  3. data/.ruby-version +1 -1
  4. data/CHANGELOG.md +10 -0
  5. data/Gemfile +21 -1
  6. data/README.md +15 -20
  7. data/introspective_grape.gemspec +41 -63
  8. data/lib/introspective_grape/api.rb +22 -12
  9. data/lib/introspective_grape/camel_snake.rb +3 -3
  10. data/lib/introspective_grape/create_helpers.rb +1 -1
  11. data/lib/introspective_grape/filters.rb +5 -3
  12. data/lib/introspective_grape/route.rb +11 -0
  13. data/lib/introspective_grape/traversal.rb +56 -56
  14. data/lib/introspective_grape/validators.rb +5 -4
  15. data/lib/introspective_grape/version.rb +1 -1
  16. data/lib/introspective_grape.rb +1 -0
  17. data/spec/dummy/Gemfile +4 -2
  18. data/spec/dummy/app/api/{api_helpers.rb → authentication_helper.rb} +2 -1
  19. data/spec/dummy/app/api/dummy/chat_api.rb +1 -1
  20. data/spec/dummy/app/api/dummy/company_api.rb +1 -1
  21. data/spec/dummy/app/api/dummy/location_api.rb +1 -1
  22. data/spec/dummy/app/api/dummy/project_api.rb +2 -2
  23. data/spec/dummy/app/api/dummy/role_api.rb +1 -1
  24. data/spec/dummy/app/api/dummy/sessions.rb +2 -2
  25. data/spec/dummy/app/api/dummy/user_api.rb +1 -1
  26. data/spec/dummy/app/api/dummy_api.rb +5 -6
  27. data/spec/dummy/app/api/error_handlers.rb +6 -6
  28. data/spec/dummy/app/api/permissions_helper.rb +1 -1
  29. data/spec/dummy/app/helpers/current.rb +3 -0
  30. data/spec/dummy/app/models/abstract_adapter.rb +11 -8
  31. data/spec/dummy/app/models/chat_message.rb +1 -1
  32. data/spec/dummy/app/models/chat_user.rb +1 -1
  33. data/spec/dummy/app/models/company.rb +3 -2
  34. data/spec/dummy/app/models/location.rb +1 -1
  35. data/spec/dummy/app/models/role.rb +1 -1
  36. data/spec/dummy/app/models/team.rb +5 -0
  37. data/spec/dummy/app/models/user/chatter.rb +2 -2
  38. data/spec/dummy/app/models/user.rb +2 -0
  39. data/spec/dummy/bin/bundle +1 -1
  40. data/spec/dummy/bin/rails +1 -1
  41. data/spec/dummy/bin/setup +20 -13
  42. data/spec/dummy/bin/update +31 -0
  43. data/spec/dummy/bin/yarn +11 -0
  44. data/spec/dummy/config/application.rb +17 -24
  45. data/spec/dummy/config/boot.rb +2 -5
  46. data/spec/dummy/config/environment.rb +1 -7
  47. data/spec/dummy/config/environments/development.rb +28 -16
  48. data/spec/dummy/config/environments/production.rb +27 -25
  49. data/spec/dummy/config/environments/test.rb +13 -10
  50. data/spec/dummy/config/initializers/application_controller_renderer.rb +8 -0
  51. data/spec/dummy/config/initializers/assets.rb +6 -3
  52. data/spec/dummy/config/initializers/content_security_policy.rb +25 -0
  53. data/spec/dummy/config/initializers/cookies_serializer.rb +2 -0
  54. data/spec/dummy/config/initializers/new_framework_defaults_5_2.rb +38 -0
  55. data/spec/dummy/config/initializers/wrap_parameters.rb +2 -2
  56. data/spec/dummy/config/locales/en.yml +10 -0
  57. data/spec/dummy/config/routes.rb +1 -1
  58. data/spec/dummy/config/storage.yml +34 -0
  59. data/spec/models/image_spec.rb +1 -5
  60. data/spec/rails_helper.rb +1 -2
  61. data/spec/requests/chat_api_spec.rb +1 -1
  62. data/spec/requests/company_api_spec.rb +1 -1
  63. data/spec/requests/location_api_spec.rb +1 -1
  64. data/spec/requests/project_api_spec.rb +5 -2
  65. data/spec/requests/role_api_spec.rb +1 -1
  66. data/spec/requests/user_api_spec.rb +2 -2
  67. data/spec/support/request_helpers.rb +4 -3
  68. metadata +23 -343
  69. data/spec/dummy/.ruby-version +0 -1
  70. data/spec/dummy/config/initializers/inflections.rb +0 -16
@@ -1,56 +1,56 @@
1
- module IntrospectiveGrape
2
- module Traversal
3
- # For deeply nested endpoints we want to present the record being affected, these
4
- # methods traverse down from the parent instance to the child model associations
5
- # of the deeply nested route.
6
-
7
- def find_leaves(routes, record, params)
8
- # Traverse down our route and find the leaf's siblings from its parent, e.g.
9
- # project/#/teams/#/team_users ~> project.find.teams.find.team_users
10
- # (the traversal of the intermediate nodes occurs in find_leaf())
11
- return record if routes.size < 2 # the leaf is the root
12
-
13
- record = find_leaf(routes, record, params) || return
14
-
15
- assoc = routes.last
16
- if assoc.many?
17
- leaves = record.send( assoc.reflection.name ).includes( default_includes(assoc.model) )
18
- verify_records_found(leaves, routes)
19
- leaves
20
- else
21
- # has_one associations don't return a CollectionProxy and so don't support
22
- # eager loading.
23
- record.send( assoc.reflection.name )
24
- end
25
- end
26
-
27
- def verify_records_found(leaves, routes)
28
- return if (leaves.map(&:class) - [routes.last.model]).empty?
29
-
30
- raise ActiveRecord::RecordNotFound.new("Records contain the wrong models, they should all be #{routes.last.model.name}, found #{records.map(&:class).map(&:name).join(',')}")
31
- end
32
-
33
- def find_leaf(routes, record, params)
34
- return record unless routes.size > 1
35
-
36
- # For deeply nested routes we need to search from the root of the API to the leaf
37
- # of its nested associations in order to guarantee the validity of the relationship,
38
- # the authorization on the parent model, and the sanity of passed parameters.
39
- routes[1..-1].each do |r|
40
- if record && params[r.key]
41
- ref = r.reflection
42
- record = record.send(ref.name).where( id: params[r.key] ).first if ref
43
- end
44
- end
45
-
46
- verify_record_found(routes, params, record)
47
- record
48
- end
49
-
50
- def verify_record_found(routes, params, record)
51
- return unless params[routes.last.key] && record.class != routes.last.model
52
-
53
- raise ActiveRecord::RecordNotFound.new("No #{routes.last.model.name} with ID '#{params[routes.last.key]}'")
54
- end
55
- end
56
- end
1
+ module IntrospectiveGrape
2
+ module Traversal
3
+ # For deeply nested endpoints we want to present the record being affected, these
4
+ # methods traverse down from the parent instance to the child model associations
5
+ # of the deeply nested route.
6
+
7
+ def find_leaves(routes, record, params)
8
+ # Traverse down our route and find the leaf's siblings from its parent, e.g.
9
+ # project/#/teams/#/team_users ~> project.find.teams.find.team_users
10
+ # (the traversal of the intermediate nodes occurs in find_leaf())
11
+ return record if routes.size < 2 # the leaf is the root
12
+
13
+ record = find_leaf(routes, record, params) || return
14
+
15
+ assoc = routes.last
16
+ if assoc.many?
17
+ leaves = record.send( assoc.reflection.name ).includes( default_includes(assoc.model) )
18
+ verify_records_found(leaves, routes)
19
+ leaves
20
+ else
21
+ # has_one associations don't return a CollectionProxy and so don't support
22
+ # eager loading.
23
+ record.send( assoc.reflection.name )
24
+ end
25
+ end
26
+
27
+ def verify_records_found(leaves, routes)
28
+ return if (leaves.map(&:class) - [routes.last.model]).empty?
29
+
30
+ raise ActiveRecord::RecordNotFound.new("Records contain the wrong models, they should all be #{routes.last.model.name}, found #{records.map(&:class).map(&:name).join(',')}")
31
+ end
32
+
33
+ def find_leaf(routes, record, params)
34
+ return record unless routes.size > 1
35
+
36
+ # For deeply nested routes we need to search from the root of the API to the leaf
37
+ # of its nested associations in order to guarantee the validity of the relationship,
38
+ # the authorization on the parent model, and the sanity of passed parameters.
39
+ routes[1..].each do |r|
40
+ if record && params[r.key]
41
+ ref = r.reflection
42
+ record = record.send(ref.name).where( id: params[r.key] ).first if ref
43
+ end
44
+ end
45
+
46
+ verify_record_found(routes, params, record)
47
+ record
48
+ end
49
+
50
+ def verify_record_found(routes, params, record)
51
+ return unless params[routes.last.key] && record.class != routes.last.model
52
+
53
+ raise ActiveRecord::RecordNotFound.new("No #{routes.last.model.name} with ID '#{params[routes.last.key]}'")
54
+ end
55
+ end
56
+ end
@@ -2,13 +2,14 @@ require 'grape/validations'
2
2
  module Grape
3
3
  module Validators
4
4
  # Validations::Base becomes Validators::Base somewhere between 1.6.0 and 1.6.2
5
- validation_class = defined?(Grape::Validations::Base) ? Grape::Validations::Base : Grape::Validations::Validators::Base
5
+ validation_class = defined?(Grape::Validations::Validators::Base) ? Grape::Validations::Validators::Base : Grape::Validations::Base
6
+
6
7
  class Json < validation_class
7
8
  def validate_param!(field, params)
8
9
  begin
9
10
  JSON.parse( params[field] )
10
11
  rescue StandardError
11
- raise Grape::Exceptions::Validation, params: [@scope.full_name(field)], message: 'must be valid JSON!'
12
+ raise Grape::Exceptions::Validation.new params: [@scope.full_name(field)], message: 'must be valid JSON!'
12
13
  end
13
14
  end
14
15
  end
@@ -18,7 +19,7 @@ module Grape
18
19
  begin
19
20
  raise unless JSON.parse( params[field] ).is_a? Array
20
21
  rescue StandardError
21
- raise Grape::Exceptions::Validation, params: [@scope.full_name(field)], message: 'must be a valid JSON array!'
22
+ raise Grape::Exceptions::Validation.new params: [@scope.full_name(field)], message: 'must be a valid JSON array!'
22
23
  end
23
24
  end
24
25
  end
@@ -28,7 +29,7 @@ module Grape
28
29
  begin
29
30
  raise unless JSON.parse( params[field] ).is_a? Hash
30
31
  rescue StandardError
31
- raise Grape::Exceptions::Validation, params: [@scope.full_name(field)], message: 'must be a valid JSON hash!'
32
+ raise Grape::Exceptions::Validation.new params: [@scope.full_name(field)], message: 'must be a valid JSON hash!'
32
33
  end
33
34
  end
34
35
  end
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module IntrospectiveGrape
4
- VERSION = '0.5.7'
4
+ VERSION = '0.7.0'
5
5
  end
@@ -9,6 +9,7 @@ module IntrospectiveGrape
9
9
  autoload :Helpers, 'introspective_grape/helpers'
10
10
  autoload :SnakeParams, 'introspective_grape/snake_params'
11
11
  autoload :Traversal, 'introspective_grape/traversal'
12
+ autoload :Route, 'introspective_grape/route'
12
13
 
13
14
  module Formatter
14
15
  autoload :CamelJson, 'introspective_grape/formatter/camel_json'
data/spec/dummy/Gemfile CHANGED
@@ -1,7 +1,8 @@
1
1
  source 'https://rubygems.org'
2
- gem 'rails', '5.2.6.2'
2
+ gem 'rails' #, '5.2.6.2'
3
3
 
4
4
  gem 'byebug'
5
+ gem 'listen'
5
6
  gem 'camel_snake_keys'
6
7
 
7
8
  gem 'devise'
@@ -13,10 +14,11 @@ gem 'grape-entity'
13
14
  gem 'grape-kaminari'
14
15
  gem 'grape-swagger'
15
16
  gem 'grape-swagger-entity'
16
- gem 'introspective_grape' #, path: '~/Dropbox/contrib/introspective_grape'
17
+ gem 'introspective_grape', path: '~/Dropbox/contrib/introspective_grape'
17
18
 
18
19
  gem 'paperclip'
19
20
  gem 'pundit'
20
21
 
21
22
  gem 'rack-cors'
22
23
  gem 'sqlite3'
24
+ gem 'validates_by_schema'
@@ -1,8 +1,9 @@
1
- module ApiHelpers
1
+ module AuthenticationHelper
2
2
  def current_user
3
3
  params[:api_key].present? && @user = User.find_by_authentication_token(params[:api_key])
4
4
  # for testing in situ
5
5
  @user = User.find_or_create_by(email: 'test@test.com', superuser: true, authentication_token: '1234567890', first_name: "First", last_name: "Last")
6
+ Current.user = @user
6
7
  end
7
8
 
8
9
  def authenticate!
@@ -1,4 +1,4 @@
1
- class Dummy::ChatAPI < Grape::API
1
+ class Dummy::ChatApi < Grape::API
2
2
  formatter :json, IntrospectiveGrape::Formatter::CamelJson
3
3
 
4
4
  before do
@@ -1,4 +1,4 @@
1
- class Dummy::CompanyAPI < IntrospectiveGrape::API
1
+ class Dummy::CompanyApi < IntrospectiveGrape::API
2
2
  paginate
3
3
 
4
4
  restful Company, [:id, :name, :short_name, :gizmos, :widgets, :sprockets] do
@@ -1,4 +1,4 @@
1
- class Dummy::LocationAPI < IntrospectiveGrape::API
1
+ class Dummy::LocationApi < IntrospectiveGrape::API
2
2
  exclude_actions Location, :none
3
3
  include_actions LocationBeacon, :index
4
4
  include_actions LocationGps, :index
@@ -1,4 +1,4 @@
1
- class Dummy::ProjectAPI < IntrospectiveGrape::API
1
+ class Dummy::ProjectApi < IntrospectiveGrape::API
2
2
  include Grape::Kaminari
3
3
 
4
4
  default_includes Project, :owner, :admins, :user_project_jobs, project_jobs: [:job], teams: [:team_users]
@@ -43,7 +43,7 @@ class Dummy::ProjectAPI < IntrospectiveGrape::API
43
43
 
44
44
  class ProjectEntity < Grape::Entity
45
45
  expose :id, :name, :created_at, :updated_at
46
- expose :owner, using: Dummy::CompanyAPI::CompanyEntity
46
+ expose :owner, using: Dummy::CompanyApi::CompanyEntity
47
47
  expose :admins, using: AdminEntity
48
48
  expose :project_jobs, as: :jobs, using: JobEntity
49
49
  expose :user_project_jobs, as: :user_jobs, using: UserJobEntity
@@ -1,4 +1,4 @@
1
- class Dummy::RoleAPI < IntrospectiveGrape::API
1
+ class Dummy::RoleApi < IntrospectiveGrape::API
2
2
  restful Role
3
3
 
4
4
  class RoleEntity < Grape::Entity
@@ -16,7 +16,7 @@ class Dummy::Sessions < Grape::API #::Instance
16
16
  if user && user.valid_password?(params[:password]) && user.valid_for_authentication?
17
17
 
18
18
  # commented out for now, User model is not yet confirmable
19
- #unauthenticated! DummyAPI::USER_NOT_CONFIRMED unless user.confirmed?
19
+ #unauthenticated! DummyApi::USER_NOT_CONFIRMED unless user.confirmed?
20
20
 
21
21
  token = nil
22
22
  if params[:token]
@@ -28,7 +28,7 @@ class Dummy::Sessions < Grape::API #::Instance
28
28
  env['warden'].set_user(user, scope: :user)
29
29
  present user, with: Dummy::Entities::User, token: token
30
30
  else
31
- unauthenticated! DummyAPI::BAD_LOGIN
31
+ unauthenticated! DummyApi::BAD_LOGIN
32
32
  end
33
33
  end
34
34
 
@@ -1,4 +1,4 @@
1
- class Dummy::UserAPI < IntrospectiveGrape::API
1
+ class Dummy::UserApi < IntrospectiveGrape::API
2
2
 
3
3
  skip_presence_validations :password
4
4
 
@@ -1,17 +1,16 @@
1
1
  require 'byebug'
2
2
  require 'grape-kaminari'
3
- class DummyAPI < Grape::API #::Instance
3
+ class DummyApi < Grape::API #::Instance
4
4
  include Grape::Kaminari
5
+ include ErrorHandlers
5
6
 
6
7
  version 'v1', using: :path
7
8
  format :json
8
9
  formatter :json, IntrospectiveGrape::Formatter::CamelJson
9
10
  default_format :json
10
11
 
11
-
12
- include ErrorHandlers
13
12
  helpers PermissionsHelper
14
- helpers ApiHelpers
13
+ helpers AuthenticationHelper
15
14
 
16
15
  USER_NOT_CONFIRMED = 'user_not_confirmed'.freeze
17
16
  BAD_LOGIN = 'bad_login'.freeze
@@ -33,11 +32,11 @@ class DummyAPI < Grape::API #::Instance
33
32
  end
34
33
 
35
34
  # Load the in-memory database for the test app
36
- load "#{Rails.root}/db/schema.rb"
35
+ # load "#{Rails.root}/db/schema.rb"
37
36
 
38
37
  # Mount every api endpoint under app/api/dummy/.
39
38
  Dir.glob(Rails.root+"app"+"api"+'dummy'+'*.rb').each do |f|
40
- api = "Dummy::#{File.basename(f, '.rb').camelize.sub(/Api$/,'API')}"
39
+ api = "Dummy::#{File.basename(f, '.rb').camelize}"
41
40
  api = api.constantize
42
41
  mount api if api.respond_to? :endpoints
43
42
  end
@@ -2,27 +2,27 @@ require 'pundit'
2
2
  module ErrorHandlers
3
3
  def self.included(m)
4
4
  m.rescue_from ActiveRecord::RecordInvalid do |e|
5
- error_response message: e.record.errors.to_a.uniq.join(', '), status: 400
5
+ error! e.record.errors.to_a.uniq.join(', '), 400
6
6
  end
7
7
 
8
8
  m.rescue_from Grape::Exceptions::ValidationErrors do |e|
9
- error_response message: e.message, status: 400
9
+ error! e.message, 400
10
10
  end
11
11
 
12
12
  m.rescue_from ActiveRecord::RecordNotFound do |e|
13
- error_response message: "Record not found! #{e.message}", status: 404
13
+ error! "Record not found! #{e.message}", 404
14
14
  end
15
15
 
16
16
  m.rescue_from ActiveRecord::InvalidForeignKey do |e|
17
- error_response message: "Join record not found! #{e.message}", status: 404
17
+ error! "Join record not found! #{e.message}", 404
18
18
  end
19
19
 
20
20
  m.rescue_from Pundit::NotAuthorizedError do
21
- error_response message: "Forbidden", status: 403
21
+ error! "Forbidden", 403
22
22
  end
23
23
 
24
24
  m.rescue_from Pundit::NotDefinedError do
25
- error_response message: "Policy not implemented", status: 501
25
+ error! "Policy not implemented", 501
26
26
  end
27
27
  end
28
28
  end
@@ -2,6 +2,6 @@ require 'pundit'
2
2
  module PermissionsHelper
3
3
  # Pundit won't import it's methods unless it sees a stub of ActionController's hide_action.
4
4
  def hide_action; end
5
- include Pundit
5
+ include Pundit::Authorization
6
6
 
7
7
  end
@@ -0,0 +1,3 @@
1
+ module Current
2
+ thread_mattr_accessor :user
3
+ end
@@ -1,13 +1,16 @@
1
1
  class AbstractAdapter < ActiveRecord::Base
2
- self.abstract_class = true
2
+ primary_abstract_class
3
3
 
4
- class << self
5
- def human_attribute_name(attr, options = {})
6
- # The default formatting of validation errors sucks, this helps a little syntatically:
7
- super.titleize+":"
8
- end
9
-
10
- end
4
+ class << self
5
+ def inherited(klass)
6
+ super
7
+ klass.validates_by_schema
8
+ end
11
9
 
10
+ def human_attribute_name(attr, options = {})
11
+ # The default formatting of validation errors sucks, this helps a little syntatically:
12
+ super.titleize+":"
13
+ end
14
+ end
12
15
  end
13
16
 
@@ -11,7 +11,7 @@ class ChatMessage < AbstractAdapter
11
11
  validate :author_in_chat
12
12
 
13
13
  def author_in_chat
14
- errors[:base] << 'User not in chat session.' unless chat.active_users.include? author
14
+ errors.add(:base, 'User not in chat session.') unless chat.active_users.include? author
15
15
  end
16
16
 
17
17
  before_save :create_message_users, if: :new_record?
@@ -10,7 +10,7 @@ class ChatUser < AbstractAdapter
10
10
  validate :user_not_already_active, on: :create
11
11
 
12
12
  def user_not_already_active
13
- errors[:base] << "#{user.name} is already present in this chat." if chat.chat_users.where(user_id: user.id, departed_at: nil).count > 0 && user.persisted?
13
+ errors.add(:base, "#{user.name} is already present in this chat.") if chat.chat_users.where(user_id: user.id, departed_at: nil).count > 0 && user.persisted?
14
14
  end
15
15
 
16
16
  end
@@ -9,8 +9,9 @@ class Company < AbstractAdapter
9
9
 
10
10
  has_many :projects, foreign_key: :owner_id, dependent: :destroy, inverse_of: :owner
11
11
 
12
- validates_length_of :name, maximum: 256
13
- validates_length_of :short_name, maximum: 10
12
+ # leave these to validates_by_schema:
13
+ # validates_length_of :name, maximum: 256
14
+ # validates_length_of :short_name, maximum: 10
14
15
 
15
16
  def self.grape_validations
16
17
  {
@@ -6,7 +6,7 @@ class Location < AbstractAdapter
6
6
  has_one :gps, class_name: 'LocationGps', dependent: :destroy
7
7
  delegate :lat,:lng,:alt, to: :gps
8
8
 
9
- belongs_to :parent_location, foreign_key: :parent_location_id, class_name: 'Location', inverse_of: :child_locations
9
+ belongs_to :parent_location, foreign_key: :parent_location_id, class_name: 'Location', inverse_of: :child_locations, optional: true
10
10
  has_many :child_locations, foreign_key: :parent_location_id, class_name: 'Location', dependent: :destroy, inverse_of: :parent_location
11
11
 
12
12
  has_many :user_locations, dependent: :destroy
@@ -1,6 +1,6 @@
1
1
  class Role < AbstractAdapter
2
2
  belongs_to :user
3
- belongs_to :ownable, polymorphic: true
3
+ belongs_to :ownable, polymorphic: true, optional: true
4
4
 
5
5
  validates_uniqueness_of :user_id, scope: [:ownable_type,:ownable_id], unless: Proc.new {|u| u.user_id.nil? }, message: "user has already been assigned that role"
6
6
  OWNABLE_TYPES = %w(Company Project).freeze
@@ -6,4 +6,9 @@ class Team < AbstractAdapter
6
6
  has_many :users, through: :team_users
7
7
  accepts_nested_attributes_for :team_users, allow_destroy: true
8
8
 
9
+ before_validation :set_creator
10
+
11
+ def set_creator
12
+ self.creator ||= Current.user
13
+ end
9
14
  end
@@ -52,7 +52,7 @@ module User::Chatter
52
52
  chat.messages.build(chat: chat, author: self, message: "#{self.name} [[ADDED_USER_MESSAGE]] #{users.map(&:name).join(',')}")
53
53
  chat.save!
54
54
  else
55
- chat.errors[:base] << "Only current chat participants can add users."
55
+ chat.errors.add(:base, "Only current chat participants can add users.")
56
56
  raise ActiveRecord::RecordInvalid.new(chat)
57
57
  end
58
58
  end
@@ -62,7 +62,7 @@ module User::Chatter
62
62
 
63
63
  if chat.active_users.include?(self)
64
64
  reply(chat, "#{name} [[DEPARTS_MESSAGE]]")
65
- chat.chat_users.detect {|cu| cu.user_id == self.id}.update_attributes(departed_at: Time.now)
65
+ chat.chat_users.detect {|cu| cu.user_id == self.id}.update(departed_at: Time.now)
66
66
  else
67
67
  true
68
68
  end
@@ -5,6 +5,8 @@ class User < AbstractAdapter
5
5
  devise :database_authenticatable, :registerable, :confirmable,
6
6
  :recoverable, :rememberable, :trackable, :validatable, :lockable
7
7
 
8
+ validates_by_schema except: :encrypted_password
9
+
8
10
  scope :active, -> { where(:locked_at => nil) }
9
11
  scope :inactive, -> { where('locked_at is not null') }
10
12
 
@@ -1,3 +1,3 @@
1
1
  #!/usr/bin/env ruby
2
- ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__)
2
+ ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../Gemfile', __dir__)
3
3
  load Gem.bin_path('bundler', 'bundle')
data/spec/dummy/bin/rails CHANGED
@@ -1,4 +1,4 @@
1
1
  #!/usr/bin/env ruby
2
- APP_PATH = File.expand_path('../../config/application', __FILE__)
2
+ APP_PATH = File.expand_path('../config/application', __dir__)
3
3
  require_relative '../config/boot'
4
4
  require 'rails/commands'
data/spec/dummy/bin/setup CHANGED
@@ -1,29 +1,36 @@
1
1
  #!/usr/bin/env ruby
2
- require 'pathname'
2
+ require 'fileutils'
3
+ include FileUtils
3
4
 
4
5
  # path to your application root.
5
- APP_ROOT = Pathname.new File.expand_path('../../', __FILE__)
6
+ APP_ROOT = File.expand_path('..', __dir__)
6
7
 
7
- Dir.chdir APP_ROOT do
8
+ def system!(*args)
9
+ system(*args) || abort("\n== Command #{args} failed ==")
10
+ end
11
+
12
+ chdir APP_ROOT do
8
13
  # This script is a starting point to setup your application.
9
- # Add necessary setup steps to this file:
14
+ # Add necessary setup steps to this file.
15
+
16
+ puts '== Installing dependencies =='
17
+ system! 'gem install bundler --conservative'
18
+ system('bundle check') || system!('bundle install')
10
19
 
11
- puts "== Installing dependencies =="
12
- system "gem install bundler --conservative"
13
- system "bundle check || bundle install"
20
+ # Install JavaScript dependencies if using Yarn
21
+ # system('bin/yarn')
14
22
 
15
23
  # puts "\n== Copying sample files =="
16
- # unless File.exist?("config/database.yml")
17
- # system "cp config/database.yml.sample config/database.yml"
24
+ # unless File.exist?('config/database.yml')
25
+ # cp 'config/database.yml.sample', 'config/database.yml'
18
26
  # end
19
27
 
20
28
  puts "\n== Preparing database =="
21
- system "bin/rake db:setup"
29
+ system! 'bin/rails db:setup'
22
30
 
23
31
  puts "\n== Removing old logs and tempfiles =="
24
- system "rm -f log/*"
25
- system "rm -rf tmp/cache"
32
+ system! 'bin/rails log:clear tmp:clear'
26
33
 
27
34
  puts "\n== Restarting application server =="
28
- system "touch tmp/restart.txt"
35
+ system! 'bin/rails restart'
29
36
  end
@@ -0,0 +1,31 @@
1
+ #!/usr/bin/env ruby
2
+ require 'fileutils'
3
+ include FileUtils
4
+
5
+ # path to your application root.
6
+ APP_ROOT = File.expand_path('..', __dir__)
7
+
8
+ def system!(*args)
9
+ system(*args) || abort("\n== Command #{args} failed ==")
10
+ end
11
+
12
+ chdir APP_ROOT do
13
+ # This script is a way to update your development environment automatically.
14
+ # Add necessary update steps to this file.
15
+
16
+ puts '== Installing dependencies =='
17
+ system! 'gem install bundler --conservative'
18
+ system('bundle check') || system!('bundle install')
19
+
20
+ # Install JavaScript dependencies if using Yarn
21
+ # system('bin/yarn')
22
+
23
+ puts "\n== Updating database =="
24
+ system! 'bin/rails db:migrate'
25
+
26
+ puts "\n== Removing old logs and tempfiles =="
27
+ system! 'bin/rails log:clear tmp:clear'
28
+
29
+ puts "\n== Restarting application server =="
30
+ system! 'bin/rails restart'
31
+ end
@@ -0,0 +1,11 @@
1
+ #!/usr/bin/env ruby
2
+ APP_ROOT = File.expand_path('..', __dir__)
3
+ Dir.chdir(APP_ROOT) do
4
+ begin
5
+ exec "yarnpkg", *ARGV
6
+ rescue Errno::ENOENT
7
+ $stderr.puts "Yarn executable was not detected in the system."
8
+ $stderr.puts "Download Yarn at https://yarnpkg.com/en/docs/install"
9
+ exit 1
10
+ end
11
+ end
@@ -1,37 +1,30 @@
1
- require File.expand_path('../boot', __FILE__)
1
+ require_relative 'boot'
2
2
 
3
+ require "rails"
3
4
  # Pick the frameworks you want:
5
+ require "active_model/railtie"
6
+ require "active_job/railtie"
4
7
  require "active_record/railtie"
8
+ require "active_storage/engine"
5
9
  require "action_controller/railtie"
6
10
  require "action_mailer/railtie"
7
11
  require "action_view/railtie"
8
- require "sprockets/railtie"
9
- require 'devise'
10
- #require 'devise/async'
11
- require 'grape-swagger'
12
- require 'grape-entity'
13
- # require "rails/test_unit/railtie"
12
+ # require "action_cable/engine"
13
+ # require "sprockets/railtie"
14
+ require "rails/test_unit/railtie"
14
15
 
15
- #Bundler.require(*Rails.groups)
16
- require "introspective_grape"
17
- require 'introspective_grape/camel_snake'
16
+ # Require the gems listed in Gemfile, including any gems
17
+ # you've limited to :test, :development, or :production.
18
+ Bundler.require(*Rails.groups)
18
19
 
19
20
  module Dummy
20
21
  class Application < Rails::Application
21
- # Settings in config/environments/* take precedence over those specified here.
22
- # Application configuration should go into files in config/initializers
23
- # -- all .rb files in that directory are automatically loaded.
24
-
25
- # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
26
- # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
27
- # config.time_zone = 'Central Time (US & Canada)'
28
-
29
- # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
30
- # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
31
- # config.i18n.default_locale = :de
32
-
33
- # Do not swallow errors in after_commit/after_rollback callbacks.
34
- #config.active_record.raise_in_transactional_callbacks = true
22
+ # Initialize configuration defaults for originally generated Rails version.
23
+ #config.load_defaults 7.0
35
24
 
25
+ # Settings in config/environments/* take precedence over those specified here.
26
+ # Application configuration can go into files in config/initializers
27
+ # -- all .rb files in that directory are automatically loaded after loading
28
+ # the framework and any gems in your application.
36
29
  end
37
30
  end