├── .ruby-version ├── spec ├── dummy │ ├── log │ │ └── .keep │ ├── app │ │ ├── mailers │ │ │ └── .keep │ │ ├── models │ │ │ ├── .keep │ │ │ ├── concerns │ │ │ │ └── .keep │ │ │ └── admin_user.rb │ │ ├── assets │ │ │ ├── images │ │ │ │ └── .keep │ │ │ ├── javascripts │ │ │ │ ├── active_admin.js.coffee │ │ │ │ └── application.js │ │ │ └── stylesheets │ │ │ │ ├── active_admin.scss │ │ │ │ └── application.css │ │ ├── controllers │ │ │ ├── concerns │ │ │ │ └── .keep │ │ │ └── application_controller.rb │ │ ├── helpers │ │ │ └── application_helper.rb │ │ ├── views │ │ │ ├── admin │ │ │ │ ├── jobs │ │ │ │ │ ├── _job_test.failed.html.erb │ │ │ │ │ ├── _job_test.finished.html.erb │ │ │ │ │ ├── _user_upload_job.finished.html.erb │ │ │ │ │ └── _user_upload_job.failed.html.erb │ │ │ │ └── admin_users │ │ │ │ │ └── import_form.html.erb │ │ │ └── layouts │ │ │ │ └── application.html.erb │ │ ├── admin │ │ │ ├── jobs.rb │ │ │ ├── dashboard.rb │ │ │ └── admin_users.rb │ │ └── jobs │ │ │ └── user_upload_job.rb │ ├── lib │ │ └── assets │ │ │ └── .keep │ ├── public │ │ ├── favicon.ico │ │ ├── 500.html │ │ ├── 422.html │ │ └── 404.html │ ├── bin │ │ ├── rake │ │ ├── bundle │ │ ├── rails │ │ ├── delayed_job │ │ └── setup │ ├── config.ru │ ├── config │ │ ├── initializers │ │ │ ├── cookies_serializer.rb │ │ │ ├── session_store.rb │ │ │ ├── mime_types.rb │ │ │ ├── filter_parameter_logging.rb │ │ │ ├── job_notifier.rb │ │ │ ├── backtrace_silencers.rb │ │ │ ├── assets.rb │ │ │ ├── wrap_parameters.rb │ │ │ ├── inflections.rb │ │ │ ├── active_admin.rb │ │ │ └── devise.rb │ │ ├── environment.rb │ │ ├── routes.rb │ │ ├── boot.rb │ │ ├── database.yml │ │ ├── locales │ │ │ ├── en.yml │ │ │ └── devise.en.yml │ │ ├── secrets.yml │ │ ├── application.rb │ │ └── environments │ │ │ ├── development.rb │ │ │ ├── test.rb │ │ │ └── production.rb │ ├── Rakefile │ ├── db │ │ ├── migrate │ │ │ ├── 20160520151817_create_job_notifier_jobs.job_notifier.rb │ │ │ ├── 20160520161115_create_active_admin_comments.rb │ │ │ ├── 20160612014504_create_delayed_jobs.rb │ │ │ └── 20160520161112_devise_create_admin_users.rb │ │ └── schema.rb │ └── README.rdoc ├── support │ ├── database_cleaner.rb │ ├── active_admin_helpers.rb │ └── capybara_helpers.rb ├── rails_helper.rb └── features │ ├── job_index_spec.rb │ ├── job_show_spec.rb │ └── notifications_spec.rb ├── app ├── assets │ ├── images │ │ └── activeadmin_jobs │ │ │ └── .keep │ ├── javascripts │ │ └── activeadmin_jobs │ │ │ ├── base.js │ │ │ ├── application.js │ │ │ └── growl_setup.js │ └── stylesheets │ │ └── activeadmin_jobs │ │ ├── base.scss │ │ └── application.css ├── helpers │ └── activeadmin_jobs │ │ └── application_helper.rb ├── controllers │ └── activeadmin_jobs │ │ └── application_controller.rb ├── views │ └── layouts │ │ └── activeadmin_jobs │ │ └── application.html.erb └── admin │ └── jobs.rb ├── .rspec ├── config ├── routes.rb └── locales │ ├── activeadmin_jobs.en.yml │ └── activeadmin_jobs.es.yml ├── .hound.yml ├── lib ├── activeadmin_jobs │ ├── version.rb │ ├── i18n_dictionary.rb │ ├── job_extensions.rb │ ├── engine.rb │ ├── job_result_renderer.rb │ └── activeadmin_config.rb ├── tasks │ └── activeadmin_jobs_tasks.rake ├── generators │ └── activeadmin_jobs │ │ └── install │ │ ├── USAGE │ │ └── install_generator.rb └── activeadmin_jobs.rb ├── docs └── images │ ├── error-view.png │ ├── jobs-list.png │ ├── import-form.png │ ├── jobs-example.gif │ ├── success-view.png │ ├── error-notification.png │ └── success-notification.png ├── .gitignore ├── bin └── rails ├── Rakefile ├── Gemfile ├── MIT-LICENSE ├── .travis.yml ├── CHANGELOG.md ├── activeadmin_jobs.gemspec ├── Gemfile.lock ├── README.md └── .rubocop.yml /.ruby-version: -------------------------------------------------------------------------------- 1 | 2.3 2 | -------------------------------------------------------------------------------- /spec/dummy/log/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /spec/dummy/app/mailers/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /spec/dummy/app/models/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /spec/dummy/lib/assets/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /spec/dummy/public/favicon.ico: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /spec/dummy/app/assets/images/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /spec/dummy/app/models/concerns/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /app/assets/images/activeadmin_jobs/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /spec/dummy/app/controllers/concerns/.keep: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --color 2 | --require rails_helper 3 | --format=doc 4 | -------------------------------------------------------------------------------- /config/routes.rb: -------------------------------------------------------------------------------- 1 | ActiveadminJobs::Engine.routes.draw do 2 | end 3 | -------------------------------------------------------------------------------- /.hound.yml: -------------------------------------------------------------------------------- 1 | --- 2 | ruby: 3 | enabled: true 4 | config_file: ".rubocop.yml" 5 | -------------------------------------------------------------------------------- /spec/dummy/app/helpers/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ApplicationHelper 2 | end 3 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/jobs/_job_test.failed.html.erb: -------------------------------------------------------------------------------- 1 | Failed <%= result.to_s %> 2 | -------------------------------------------------------------------------------- /lib/activeadmin_jobs/version.rb: -------------------------------------------------------------------------------- 1 | module ActiveadminJobs 2 | VERSION = "0.5.2" 3 | end 4 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/jobs/_job_test.finished.html.erb: -------------------------------------------------------------------------------- 1 | Finished <%= result.to_s %> 2 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/jobs/_user_upload_job.finished.html.erb: -------------------------------------------------------------------------------- 1 | <%= result.to_s %> 2 | -------------------------------------------------------------------------------- /docs/images/error-view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/platanus/activeadmin_jobs/HEAD/docs/images/error-view.png -------------------------------------------------------------------------------- /docs/images/jobs-list.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/platanus/activeadmin_jobs/HEAD/docs/images/jobs-list.png -------------------------------------------------------------------------------- /docs/images/import-form.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/platanus/activeadmin_jobs/HEAD/docs/images/import-form.png -------------------------------------------------------------------------------- /docs/images/jobs-example.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/platanus/activeadmin_jobs/HEAD/docs/images/jobs-example.gif -------------------------------------------------------------------------------- /docs/images/success-view.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/platanus/activeadmin_jobs/HEAD/docs/images/success-view.png -------------------------------------------------------------------------------- /app/helpers/activeadmin_jobs/application_helper.rb: -------------------------------------------------------------------------------- 1 | module ActiveadminJobs 2 | module ApplicationHelper 3 | end 4 | end 5 | -------------------------------------------------------------------------------- /spec/dummy/app/assets/javascripts/active_admin.js.coffee: -------------------------------------------------------------------------------- 1 | #= require active_admin/base 2 | #= require activeadmin_jobs/base 3 | -------------------------------------------------------------------------------- /spec/dummy/bin/rake: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require_relative '../config/boot' 3 | require 'rake' 4 | Rake.application.run 5 | -------------------------------------------------------------------------------- /docs/images/error-notification.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/platanus/activeadmin_jobs/HEAD/docs/images/error-notification.png -------------------------------------------------------------------------------- /docs/images/success-notification.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/platanus/activeadmin_jobs/HEAD/docs/images/success-notification.png -------------------------------------------------------------------------------- /app/assets/javascripts/activeadmin_jobs/base.js: -------------------------------------------------------------------------------- 1 | //= require growl 2 | //= require job_notifier/notifier 3 | //= require ./growl_setup 4 | -------------------------------------------------------------------------------- /lib/tasks/activeadmin_jobs_tasks.rake: -------------------------------------------------------------------------------- 1 | # desc "Explaining what the task does" 2 | # task :activeadmin_jobs do 3 | # # Task goes here 4 | # end 5 | -------------------------------------------------------------------------------- /spec/dummy/bin/bundle: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../Gemfile', __FILE__) 3 | load Gem.bin_path('bundler', 'bundle') 4 | -------------------------------------------------------------------------------- /lib/generators/activeadmin_jobs/install/USAGE: -------------------------------------------------------------------------------- 1 | Description: 2 | Install the engine in host app. 3 | 4 | Example: 5 | rails generate activeadmin_jobs:install 6 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | .bundle/ 2 | log/*.log 3 | pkg/ 4 | spec/dummy/db/*.sqlite3 5 | spec/dummy/db/*.sqlite3-journal 6 | spec/dummy/log/*.log 7 | spec/dummy/tmp/ 8 | spec/dummy/.sass-cache 9 | -------------------------------------------------------------------------------- /spec/dummy/bin/rails: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | APP_PATH = File.expand_path('../../config/application', __FILE__) 3 | require_relative '../config/boot' 4 | require 'rails/commands' 5 | -------------------------------------------------------------------------------- /spec/dummy/app/admin/jobs.rb: -------------------------------------------------------------------------------- 1 | # ActiveAdmin.register JobNotifier::Job, as: "Job" do 2 | # index do 3 | # selectable_column 4 | # id_column 5 | # actions 6 | # end 7 | # end 8 | -------------------------------------------------------------------------------- /spec/dummy/config.ru: -------------------------------------------------------------------------------- 1 | # This file is used by Rack-based servers to start the application. 2 | 3 | require ::File.expand_path('../config/environment', __FILE__) 4 | run Rails.application 5 | -------------------------------------------------------------------------------- /spec/dummy/config/initializers/cookies_serializer.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | Rails.application.config.action_dispatch.cookies_serializer = :json 4 | -------------------------------------------------------------------------------- /spec/dummy/config/initializers/session_store.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | Rails.application.config.session_store :cookie_store, key: '_dummy_session' 4 | -------------------------------------------------------------------------------- /spec/dummy/config/environment.rb: -------------------------------------------------------------------------------- 1 | # Load the Rails application. 2 | require File.expand_path('../application', __FILE__) 3 | 4 | # Initialize the Rails application. 5 | Rails.application.initialize! 6 | -------------------------------------------------------------------------------- /app/controllers/activeadmin_jobs/application_controller.rb: -------------------------------------------------------------------------------- 1 | module ActiveadminJobs 2 | class ApplicationController < ActionController::Base 3 | protect_from_forgery with: :exception 4 | end 5 | end 6 | -------------------------------------------------------------------------------- /lib/activeadmin_jobs.rb: -------------------------------------------------------------------------------- 1 | require "job_notifier" 2 | require "devise" 3 | require "activeadmin" 4 | require "activeadmin_addons" 5 | require "activeadmin_jobs/engine" 6 | 7 | module ActiveadminJobs 8 | end 9 | -------------------------------------------------------------------------------- /spec/dummy/config/routes.rb: -------------------------------------------------------------------------------- 1 | Rails.application.routes.draw do 2 | devise_for :admin_users, ActiveAdmin::Devise.config 3 | ActiveAdmin.routes(self) 4 | mount JobNotifier::Engine => "/job_notifier" 5 | end 6 | -------------------------------------------------------------------------------- /spec/dummy/config/initializers/mime_types.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new mime types for use in respond_to blocks: 4 | # Mime::Type.register "text/richtext", :rtf 5 | -------------------------------------------------------------------------------- /spec/dummy/bin/delayed_job: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require File.expand_path(File.join(File.dirname(__FILE__), '..', 'config', 'environment')) 4 | require 'delayed/command' 5 | Delayed::Command.new(ARGV).daemonize 6 | -------------------------------------------------------------------------------- /lib/activeadmin_jobs/i18n_dictionary.rb: -------------------------------------------------------------------------------- 1 | module I18nDictionary 2 | def self.translations 3 | I18n.backend.load_translations 4 | translations = I18n.backend.send(:translations) 5 | translations[I18n.locale][:activeadmin_jobs] 6 | end 7 | end 8 | -------------------------------------------------------------------------------- /spec/dummy/config/initializers/filter_parameter_logging.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Configure sensitive parameters which will be filtered from the log file. 4 | Rails.application.config.filter_parameters += [:password] 5 | -------------------------------------------------------------------------------- /spec/dummy/app/controllers/application_controller.rb: -------------------------------------------------------------------------------- 1 | class ApplicationController < ActionController::Base 2 | # Prevent CSRF attacks by raising an exception. 3 | # For APIs, you may want to use :null_session instead. 4 | protect_from_forgery with: :exception 5 | end 6 | -------------------------------------------------------------------------------- /spec/dummy/config/boot.rb: -------------------------------------------------------------------------------- 1 | # Set up gems listed in the Gemfile. 2 | ENV['BUNDLE_GEMFILE'] ||= File.expand_path('../../../../Gemfile', __FILE__) 3 | 4 | require 'bundler/setup' if File.exist?(ENV['BUNDLE_GEMFILE']) 5 | $LOAD_PATH.unshift File.expand_path('../../../../lib', __FILE__) 6 | -------------------------------------------------------------------------------- /spec/dummy/Rakefile: -------------------------------------------------------------------------------- 1 | # Add your own tasks in files placed in lib/tasks ending in .rake, 2 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake. 3 | 4 | require File.expand_path('../config/application', __FILE__) 5 | 6 | Rails.application.load_tasks 7 | -------------------------------------------------------------------------------- /spec/dummy/config/initializers/job_notifier.rb: -------------------------------------------------------------------------------- 1 | JobNotifier.setup do |config| 2 | # If you're using an app client that is not part of rails project where Job Notifier gem was 3 | # installed, you can define a custom root_url. For example: "http://app.platan.us/" 4 | # config.root_url = "/" 5 | end 6 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/jobs/_user_upload_job.failed.html.erb: -------------------------------------------------------------------------------- 1 |

Errors :(

2 | 3 | <% result.each do |record| %> 4 |

Row #<%= record[:row] %>:

5 | 10 | <% end %> 11 | -------------------------------------------------------------------------------- /lib/activeadmin_jobs/job_extensions.rb: -------------------------------------------------------------------------------- 1 | module ActiveadminJobs 2 | module JobExtensions 3 | def description 4 | I18n.t!("activeadmin_jobs.#{job_class.demodulize.tableize.singularize}.description") 5 | rescue I18n::MissingTranslationData 6 | "" 7 | end 8 | end 9 | end 10 | 11 | JobNotifier::Job.send(:include, ActiveadminJobs::JobExtensions) 12 | -------------------------------------------------------------------------------- /app/views/layouts/activeadmin_jobs/application.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | ActiveadminJobs 5 | <%= stylesheet_link_tag "activeadmin_jobs/application", media: "all" %> 6 | <%= javascript_include_tag "activeadmin_jobs/application" %> 7 | <%= csrf_meta_tags %> 8 | 9 | 10 | 11 | <%= yield %> 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /spec/dummy/app/models/admin_user.rb: -------------------------------------------------------------------------------- 1 | class AdminUser < ActiveRecord::Base 2 | include JobNotifier::Identifier 3 | 4 | identify_job_through :id, :email 5 | 6 | # Include default devise modules. Others available are: 7 | # :confirmable, :lockable, :timeoutable and :omniauthable 8 | devise :database_authenticatable, :recoverable, :rememberable, :trackable, :validatable 9 | end 10 | -------------------------------------------------------------------------------- /spec/dummy/app/views/layouts/application.html.erb: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | Dummy 5 | <%= stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track' => true %> 6 | <%= javascript_include_tag 'application', 'data-turbolinks-track' => true %> 7 | <%= csrf_meta_tags %> 8 | 9 | 10 | 11 | <%= yield %> 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /spec/dummy/app/views/admin/admin_users/import_form.html.erb: -------------------------------------------------------------------------------- 1 | <%= semantic_form_for :data, url: { action: :import }, html: { multipart: true }, method: :post do |f| %> 2 | <%= f.inputs "Form" do %> 3 | <%= f.input :source, as: :file, label: "File", :hint => "Excel file with thousands rows that need to be processed in background..." %> 4 | <% end %> 5 | <%= f.actions do %> 6 | <%= f.action :submit, as: :button, label: "Import" %> 7 | <% end %> 8 | <% end %> 9 | -------------------------------------------------------------------------------- /app/assets/stylesheets/activeadmin_jobs/base.scss: -------------------------------------------------------------------------------- 1 | @import "growl"; 2 | 3 | $pending-color: #e67e22; 4 | $failed-color: #c0392b; 5 | $finished-color: #27ae60; 6 | 7 | .status_tag { 8 | &.pending { background: $pending-color; } 9 | &.failed { background: $failed-color; } 10 | &.finished { background: $finished-color; } 11 | } 12 | 13 | .growl { 14 | a { 15 | &:link, &:visited, &:hover, &:active { 16 | color: #FFFFFF; 17 | } 18 | } 19 | } 20 | -------------------------------------------------------------------------------- /spec/dummy/config/initializers/backtrace_silencers.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # You can add backtrace silencers for libraries that you're using but don't wish to see in your backtraces. 4 | # Rails.backtrace_cleaner.add_silencer { |line| line =~ /my_noisy_library/ } 5 | 6 | # You can also remove all the silencers if you're trying to debug a problem that might stem from framework code. 7 | # Rails.backtrace_cleaner.remove_silencers! 8 | -------------------------------------------------------------------------------- /lib/activeadmin_jobs/engine.rb: -------------------------------------------------------------------------------- 1 | module ActiveadminJobs 2 | class Engine < ::Rails::Engine 3 | isolate_namespace ActiveadminJobs 4 | 5 | config.generators do |g| 6 | g.test_framework :rspec, fixture: false 7 | end 8 | 9 | initializer "initialize" do 10 | require_relative "./i18n_dictionary" 11 | require_relative "./job_result_renderer" 12 | require_relative "./activeadmin_config" 13 | require_relative "./job_extensions" 14 | end 15 | end 16 | end 17 | -------------------------------------------------------------------------------- /spec/support/database_cleaner.rb: -------------------------------------------------------------------------------- 1 | require "database_cleaner" 2 | 3 | RSpec.configure do |config| 4 | config.use_transactional_fixtures = false 5 | 6 | config.before(:suite) do 7 | DatabaseCleaner.clean_with(:truncation) 8 | end 9 | 10 | config.before(:each) do |example| 11 | DatabaseCleaner.strategy = example.metadata[:js] ? :truncation : :transaction 12 | DatabaseCleaner.start 13 | end 14 | 15 | config.after(:each) do 16 | DatabaseCleaner.clean 17 | end 18 | end 19 | -------------------------------------------------------------------------------- /spec/dummy/app/jobs/user_upload_job.rb: -------------------------------------------------------------------------------- 1 | class UserUploadJob < ActiveJob::Base 2 | def perform_with_feedback(result) 3 | sleep([*5..20].sample) # faking processing time 4 | return "Users successfully loaded" if result 5 | 6 | errors = [ 7 | { row: 4, errors: ["Invalid First Name", "Invalid Category"] }, 8 | { row: 6, errors: ["Invalid Last Name"] }, 9 | { row: 84, errors: ["Invalid ID"] } 10 | ] 11 | 12 | raise JobNotifier::Error::Validation.new(errors) 13 | end 14 | end 15 | -------------------------------------------------------------------------------- /bin/rails: -------------------------------------------------------------------------------- 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/activeadmin_jobs/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' 13 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20160520151817_create_job_notifier_jobs.job_notifier.rb: -------------------------------------------------------------------------------- 1 | # This migration comes from job_notifier (originally 20160401185325) 2 | class CreateJobNotifierJobs < ActiveRecord::Migration 3 | def change 4 | create_table :job_notifier_jobs do |t| 5 | t.string :identifier, index: true 6 | t.string :job_id, index: true 7 | t.string :job_class 8 | t.string :status 9 | t.text :result 10 | t.boolean :notified, default: false 11 | 12 | t.timestamps null: false 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /spec/dummy/config/initializers/assets.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Version of your assets, change this if you want to expire all your assets. 4 | Rails.application.config.assets.version = '1.0' 5 | 6 | # Add additional assets to the asset load path 7 | # Rails.application.config.assets.paths << Emoji.images_path 8 | 9 | # Precompile additional assets. 10 | # application.js, application.css, and all non-JS/CSS in app/assets folder are already added. 11 | # Rails.application.config.assets.precompile += %w( search.js ) 12 | -------------------------------------------------------------------------------- /spec/dummy/config/initializers/wrap_parameters.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # This file contains settings for ActionController::ParamsWrapper which 4 | # is enabled by default. 5 | 6 | # Enable parameter wrapping for JSON. You can disable this by setting :format to an empty array. 7 | ActiveSupport.on_load(:action_controller) do 8 | wrap_parameters format: [:json] if respond_to?(:wrap_parameters) 9 | end 10 | 11 | # To enable root element in JSON for ActiveRecord objects. 12 | # ActiveSupport.on_load(:active_record) do 13 | # self.include_root_in_json = true 14 | # end 15 | -------------------------------------------------------------------------------- /spec/dummy/README.rdoc: -------------------------------------------------------------------------------- 1 | == README 2 | 3 | This README would normally document whatever steps are necessary to get the 4 | application up and running. 5 | 6 | Things you may want to cover: 7 | 8 | * Ruby version 9 | 10 | * System dependencies 11 | 12 | * Configuration 13 | 14 | * Database creation 15 | 16 | * Database initialization 17 | 18 | * How to run the test suite 19 | 20 | * Services (job queues, cache servers, search engines, etc.) 21 | 22 | * Deployment instructions 23 | 24 | * ... 25 | 26 | 27 | Please feel free to use a different markup language if you do not plan to run 28 | rake doc:app. 29 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | begin 2 | require 'bundler/setup' 3 | rescue LoadError 4 | puts 'You must `gem install bundler` and `bundle install` to run rake tasks' 5 | end 6 | 7 | require 'rdoc/task' 8 | 9 | RDoc::Task.new(:rdoc) do |rdoc| 10 | rdoc.rdoc_dir = 'rdoc' 11 | rdoc.title = 'ActiveadminJobs' 12 | rdoc.options << '--line-numbers' 13 | rdoc.rdoc_files.include('README.rdoc') 14 | rdoc.rdoc_files.include('lib/**/*.rb') 15 | end 16 | 17 | APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__) 18 | load 'rails/tasks/engine.rake' 19 | load 'rails/tasks/statistics.rake' 20 | 21 | Bundler::GemHelper.install_tasks 22 | -------------------------------------------------------------------------------- /config/locales/activeadmin_jobs.en.yml: -------------------------------------------------------------------------------- 1 | en: 2 | enumerize: 3 | job_notifier/job: 4 | status: 5 | failed: Failed 6 | finished: Finished 7 | pending: Pending 8 | activerecord: 9 | models: 10 | job: 11 | one: Job 12 | other: Jobs 13 | attributes: 14 | job_notifier/job: 15 | id: ID 16 | identifier: Identifier 17 | job_id: Job ID 18 | job_class: Job Type 19 | status: Status 20 | result: Result 21 | description: Description 22 | notified: Notified? 23 | created_at: Created At 24 | updated_at: Updated At 25 | -------------------------------------------------------------------------------- /spec/dummy/config/database.yml: -------------------------------------------------------------------------------- 1 | # SQLite version 3.x 2 | # gem install sqlite3 3 | # 4 | # Ensure the SQLite 3 gem is defined in your Gemfile 5 | # gem 'sqlite3' 6 | # 7 | default: &default 8 | adapter: sqlite3 9 | pool: 5 10 | timeout: 5000 11 | 12 | development: 13 | <<: *default 14 | database: db/development.sqlite3 15 | 16 | # Warning: The database defined as "test" will be erased and 17 | # re-generated from your development database when you run "rake". 18 | # Do not set this db to the same as development or production. 19 | test: 20 | <<: *default 21 | database: db/test.sqlite3 22 | 23 | production: 24 | <<: *default 25 | database: db/production.sqlite3 26 | -------------------------------------------------------------------------------- /config/locales/activeadmin_jobs.es.yml: -------------------------------------------------------------------------------- 1 | es: 2 | enumerize: 3 | job_notifier/job: 4 | status: 5 | failed: Con Errores 6 | finished: Completo 7 | pending: Pendiente 8 | activerecord: 9 | models: 10 | job: 11 | one: Proceso 12 | other: Procesos 13 | attributes: 14 | job_notifier/job: 15 | id: ID 16 | identifier: Identificador 17 | job_id: ID Proceso 18 | job_class: Tipo 19 | status: Estado 20 | result: Resultado 21 | description: Descripción 22 | notified: Notificado? 23 | created_at: Fecha de Creación 24 | updated_at: Fecha de Actualización 25 | -------------------------------------------------------------------------------- /spec/dummy/app/assets/javascripts/application.js: -------------------------------------------------------------------------------- 1 | // This is a manifest file that'll be compiled into application.js, which will include all the files 2 | // listed below. 3 | // 4 | // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts, 5 | // or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path. 6 | // 7 | // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the 8 | // compiled file. 9 | // 10 | // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details 11 | // about supported directives. 12 | // 13 | //= require_tree . 14 | -------------------------------------------------------------------------------- /app/assets/javascripts/activeadmin_jobs/application.js: -------------------------------------------------------------------------------- 1 | // This is a manifest file that'll be compiled into application.js, which will include all the files 2 | // listed below. 3 | // 4 | // Any JavaScript/Coffee file within this directory, lib/assets/javascripts, vendor/assets/javascripts, 5 | // or any plugin's vendor/assets/javascripts directory can be referenced here using a relative path. 6 | // 7 | // It's not advisable to add code directly here, but if you do, it'll appear at the bottom of the 8 | // compiled file. 9 | // 10 | // Read Sprockets README (https://github.com/rails/sprockets#sprockets-directives) for details 11 | // about supported directives. 12 | // 13 | //= require_tree . 14 | -------------------------------------------------------------------------------- /lib/activeadmin_jobs/job_result_renderer.rb: -------------------------------------------------------------------------------- 1 | module ActiveadminJobs 2 | class JobResultRenderer 3 | attr_reader :page, :job, :result 4 | 5 | def initialize(page) 6 | @page = page 7 | @job = @page.resource 8 | @result = @job.result 9 | end 10 | 11 | def render 12 | page.render(partial: partial_path, locals: { job: job, result: formatted_result }) 13 | end 14 | 15 | private 16 | 17 | def partial_path 18 | "#{job.job_class.demodulize.tableize.singularize}.#{job.status}.html.erb" 19 | end 20 | 21 | def formatted_result 22 | eval(job.result) 23 | rescue Exception 24 | job.result 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /spec/rails_helper.rb: -------------------------------------------------------------------------------- 1 | # This file is copied to spec/ when you run 'rails generate rspec:install' 2 | ENV["RAILS_ENV"] ||= "test" 3 | require File.expand_path("../dummy/config/environment", __FILE__) 4 | # Prevent database truncation if the environment is production 5 | abort("The Rails environment is running in production mode!") if Rails.env.production? 6 | require "rspec/rails" 7 | 8 | engine_path = File.join(File.dirname(__FILE__), '../') 9 | Dir[File.join(engine_path, "spec/support/**/*.rb")].each { |f| require f } 10 | 11 | RSpec.configure do |config| 12 | config.filter_run focus: true 13 | config.filter_run_excluding skip: true 14 | config.run_all_when_everything_filtered = true 15 | end 16 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20160520161115_create_active_admin_comments.rb: -------------------------------------------------------------------------------- 1 | class CreateActiveAdminComments < ActiveRecord::Migration 2 | def self.up 3 | create_table :active_admin_comments do |t| 4 | t.string :namespace 5 | t.text :body 6 | t.string :resource_id, null: false 7 | t.string :resource_type, null: false 8 | t.references :author, polymorphic: true 9 | t.timestamps 10 | end 11 | add_index :active_admin_comments, [:namespace] 12 | add_index :active_admin_comments, [:author_type, :author_id] 13 | add_index :active_admin_comments, [:resource_type, :resource_id] 14 | end 15 | 16 | def self.down 17 | drop_table :active_admin_comments 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source 'https://rubygems.org' 2 | 3 | source 'https://rails-assets.org' do 4 | gem 'rails-assets-growl', '~> 1.3.1' 5 | end 6 | 7 | # Declare your gem's dependencies in activeadmin_jobs.gemspec. 8 | # Bundler will treat runtime dependencies like base dependencies, and 9 | # development dependencies will be added by default to the :development group. 10 | gemspec 11 | 12 | # Declare any dependencies that are still in development here instead of in 13 | # your gemspec. These might include edge Rails or gems from your path or 14 | # Git. Remember to move these dependencies to your gemspec before releasing 15 | # your gem to rubygems.org. 16 | 17 | # To use a debugger 18 | # gem 'byebug', group: [:development, :test] 19 | -------------------------------------------------------------------------------- /spec/dummy/app/assets/stylesheets/active_admin.scss: -------------------------------------------------------------------------------- 1 | // SASS variable overrides must be declared before loading up Active Admin's styles. 2 | // 3 | // To view the variables that Active Admin provides, take a look at 4 | // `app/assets/stylesheets/active_admin/mixins/_variables.css.scss` in the 5 | // Active Admin source. 6 | // 7 | // For example, to change the sidebar width: 8 | // $sidebar-width: 242px; 9 | 10 | // Active Admin's got SASS! 11 | @import "active_admin/mixins"; 12 | @import "active_admin/base"; 13 | @import "activeadmin_jobs/base"; 14 | 15 | // Overriding any non-variable SASS must be done after the fact. 16 | // For example, to change the default status-tag color: 17 | // 18 | // .status_tag { background: #6090DB; } 19 | -------------------------------------------------------------------------------- /spec/dummy/config/initializers/inflections.rb: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Add new inflection rules using the following format. Inflections 4 | # are locale specific, and you may define rules for as many different 5 | # locales as you wish. All of these examples are active by default: 6 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 7 | # inflect.plural /^(ox)$/i, '\1en' 8 | # inflect.singular /^(ox)en/i, '\1' 9 | # inflect.irregular 'person', 'people' 10 | # inflect.uncountable %w( fish sheep ) 11 | # end 12 | 13 | # These inflection rules are supported but not enabled by default: 14 | # ActiveSupport::Inflector.inflections(:en) do |inflect| 15 | # inflect.acronym 'RESTful' 16 | # end 17 | -------------------------------------------------------------------------------- /spec/dummy/app/assets/stylesheets/application.css: -------------------------------------------------------------------------------- 1 | /* 2 | * This is a manifest file that'll be compiled into application.css, which will include all the files 3 | * listed below. 4 | * 5 | * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets, 6 | * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path. 7 | * 8 | * You're free to add application-wide styles to this file and they'll appear at the bottom of the 9 | * compiled file so the styles you add here take precedence over styles defined in any styles 10 | * defined in the other CSS/SCSS files in this directory. It is generally better to create a new 11 | * file per style scope. 12 | * 13 | *= require_tree . 14 | *= require_self 15 | */ 16 | -------------------------------------------------------------------------------- /app/assets/stylesheets/activeadmin_jobs/application.css: -------------------------------------------------------------------------------- 1 | /* 2 | * This is a manifest file that'll be compiled into application.css, which will include all the files 3 | * listed below. 4 | * 5 | * Any CSS and SCSS file within this directory, lib/assets/stylesheets, vendor/assets/stylesheets, 6 | * or any plugin's vendor/assets/stylesheets directory can be referenced here using a relative path. 7 | * 8 | * You're free to add application-wide styles to this file and they'll appear at the bottom of the 9 | * compiled file so the styles you add here take precedence over styles defined in any styles 10 | * defined in the other CSS/SCSS files in this directory. It is generally better to create a new 11 | * file per style scope. 12 | * 13 | *= require_tree . 14 | *= require_self 15 | */ 16 | -------------------------------------------------------------------------------- /app/admin/jobs.rb: -------------------------------------------------------------------------------- 1 | ActiveAdmin.register JobNotifier::Job, as: "Job" do 2 | actions :index, :show 3 | 4 | filter :status 5 | filter :created_at 6 | 7 | controller do 8 | def scoped_collection 9 | user = send(ActiveAdmin.application.current_user_method) 10 | JobNotifier::Job.where(identifier: user.job_identifier) 11 | end 12 | end 13 | 14 | index do 15 | id_column 16 | tag_column :status 17 | column :description 18 | column :created_at 19 | actions 20 | end 21 | 22 | show do 23 | attributes_table do 24 | row :id 25 | tag_row :status 26 | row :description 27 | row :created_at 28 | end 29 | 30 | if !resource.result.blank? 31 | panel JobNotifier::Job.human_attribute_name(:result) do 32 | ActiveadminJobs::JobResultRenderer.new(self).render 33 | end 34 | end 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /spec/support/active_admin_helpers.rb: -------------------------------------------------------------------------------- 1 | engine_path = File.join(File.dirname(__FILE__), '../') 2 | # Require admin pages from dummy app 3 | Dir[File.join(engine_path, "spec/dummy/app/admin/*.rb")].each { |f| require f } 4 | 5 | module ActiveAdminHelpers 6 | def login_admin_user 7 | admin_user = AdminUser.create!(email: "admin@example.com", password: 12345678) 8 | login_as(admin_user, scope: :admin_user) 9 | admin_user 10 | end 11 | 12 | def logout_admin_user 13 | logout(:admin_user) 14 | end 15 | end 16 | 17 | RSpec.configure do |config| 18 | config.before(:suite) do 19 | Rails.application.reload_routes! # To generate routes for /app/admin and /spec/dummy/app/admin. 20 | Warden.test_mode! 21 | end 22 | 23 | config.after(:each) do 24 | Warden.test_reset! 25 | end 26 | 27 | config.include Warden::Test::Helpers 28 | config.include ActiveAdminHelpers 29 | end 30 | -------------------------------------------------------------------------------- /lib/generators/activeadmin_jobs/install/install_generator.rb: -------------------------------------------------------------------------------- 1 | class ActiveadminJobs::InstallGenerator < Rails::Generators::Base 2 | def add_javascripts 3 | file_path = "app/assets/javascripts/active_admin.js.coffee" 4 | line_to_add = "#= require activeadmin_jobs/base\n" 5 | reference = "#= require active_admin/base\n" 6 | inject_into_file(file_path, line_to_add, after: reference) 7 | end 8 | 9 | def add_stylesheets 10 | file_path = 'app/assets/stylesheets/active_admin' 11 | line_to_add = "@import \"activeadmin_jobs/base\";\n" 12 | reference = "@import \"active_admin/base\";\n" 13 | inject_into_file("#{file_path}.scss", line_to_add, after: reference) 14 | 15 | rescue Errno::ENOENT 16 | inject_into_file("#{file_path}.css.scss", line_to_add, after: reference) 17 | end 18 | 19 | def run_job_notifier_generator 20 | generate("job_notifier:install") 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /spec/dummy/config/locales/en.yml: -------------------------------------------------------------------------------- 1 | en: 2 | activeadmin_jobs: 3 | user_upload_job: 4 | description: "Users upload through .xls file" 5 | finished: 6 | title: "Users have been uploaded! :)" 7 | one: "One .xls file was completed with no errors. Click here to see the result" 8 | other: ".xls files were completed with no errors. Click here to see the result" 9 | failed: 10 | title: "Error trying to upload users :(" 11 | one: "One .xls file could not be uploaded. Click here to see errors" 12 | other: ".xls files could not be uploaded. Click here to see errors" 13 | job_test: 14 | finished: 15 | title: "Finished Job!" 16 | one: "the job was completed! :)" 17 | other: "jobs were completed! :)" 18 | failed: 19 | title: "Failed Job" 20 | one: "the job was not completed :(" 21 | other: "jobs were not completed :(" 22 | -------------------------------------------------------------------------------- /spec/features/job_index_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | describe "Job index", type: :feature do 4 | context "index view" do 5 | before do 6 | @admin = login_admin_user 7 | @job = create_job(identifier: @admin.job_identifier, notified: false) 8 | visit admin_jobs_path 9 | end 10 | 11 | it "shows jobs table" do 12 | expect(page).to have_content "Displaying 1 Job" 13 | end 14 | 15 | it "shows id column" do 16 | col = find_column(:id) 17 | expect(col.text).to eq(@job.id.to_s) 18 | end 19 | 20 | it "shows status column" do 21 | col = find_column(:status) 22 | expect(col[:class]).to eq("status_tag pending") 23 | expect(col.text).to eq("Pending") 24 | end 25 | 26 | it "shows created at column" do 27 | col = find_column(:created_at) 28 | expect(col.text).to eq(I18n.l(@job.created_at, format: :long)) 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /spec/dummy/bin/setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | require 'pathname' 3 | 4 | # path to your application root. 5 | APP_ROOT = Pathname.new File.expand_path('../../', __FILE__) 6 | 7 | Dir.chdir APP_ROOT do 8 | # This script is a starting point to setup your application. 9 | # Add necessary setup steps to this file: 10 | 11 | puts "== Installing dependencies ==" 12 | system "gem install bundler --conservative" 13 | system "bundle check || bundle install" 14 | 15 | # puts "\n== Copying sample files ==" 16 | # unless File.exist?("config/database.yml") 17 | # system "cp config/database.yml.sample config/database.yml" 18 | # end 19 | 20 | puts "\n== Preparing database ==" 21 | system "bin/rake db:setup" 22 | 23 | puts "\n== Removing old logs and tempfiles ==" 24 | system "rm -f log/*" 25 | system "rm -rf tmp/cache" 26 | 27 | puts "\n== Restarting application server ==" 28 | system "touch tmp/restart.txt" 29 | end 30 | -------------------------------------------------------------------------------- /spec/dummy/app/admin/dashboard.rb: -------------------------------------------------------------------------------- 1 | ActiveAdmin.register_page "Dashboard" do 2 | 3 | menu priority: 1, label: proc{ I18n.t("active_admin.dashboard") } 4 | 5 | content title: proc{ I18n.t("active_admin.dashboard") } do 6 | div class: "blank_slate_container", id: "dashboard_default_message" do 7 | span class: "blank_slate" do 8 | span I18n.t("active_admin.dashboard_welcome.welcome") 9 | small I18n.t("active_admin.dashboard_welcome.call_to_action") 10 | end 11 | end 12 | 13 | # Here is an example of a simple dashboard with columns and panels. 14 | # 15 | # columns do 16 | # column do 17 | # panel "Recent Posts" do 18 | # ul do 19 | # Post.recent(5).map do |post| 20 | # li link_to(post.title, admin_post_path(post)) 21 | # end 22 | # end 23 | # end 24 | # end 25 | 26 | # column do 27 | # panel "Info" do 28 | # para "Welcome to ActiveAdmin." 29 | # end 30 | # end 31 | # end 32 | end # content 33 | end 34 | -------------------------------------------------------------------------------- /spec/dummy/config/secrets.yml: -------------------------------------------------------------------------------- 1 | # Be sure to restart your server when you modify this file. 2 | 3 | # Your secret key is used for verifying the integrity of signed cookies. 4 | # If you change this key, all old signed cookies will become invalid! 5 | 6 | # Make sure the secret is at least 30 characters and all random, 7 | # no regular words or you'll be exposed to dictionary attacks. 8 | # You can use `rake secret` to generate a secure secret key. 9 | 10 | # Make sure the secrets in this file are kept private 11 | # if you're sharing your code publicly. 12 | 13 | development: 14 | secret_key_base: ec9aa883d1567ae0983fb818c4acb77ac448c54ca9c15b0e25fd8dd1f1fdeee9c0c6b74dcaf42c77b5e1dcd560ca4251408c0284e400190b5ba5c30aae8514ae 15 | 16 | test: 17 | secret_key_base: dc0d4a5c6b29e7be344a0e92ad18958b507cab2e3b680c6f33109112ea31758285f828dc838b65bc78f2760d8f763f108fb332b82723203dd3579caae2410cfd 18 | 19 | # Do not keep production secrets in the repository, 20 | # instead read values from the environment. 21 | production: 22 | secret_key_base: <%= ENV["SECRET_KEY_BASE"] %> 23 | -------------------------------------------------------------------------------- /lib/activeadmin_jobs/activeadmin_config.rb: -------------------------------------------------------------------------------- 1 | module AdminHelpers 2 | def self.jobs_url 3 | url = ["/"] 4 | 5 | if ActiveAdmin.application.default_namespace.present? 6 | url << "#{ActiveAdmin.application.default_namespace}/" 7 | end 8 | 9 | url << "jobs" 10 | url.join("") 11 | end 12 | end 13 | 14 | ActiveAdmin.application.load_paths += [File.join(ActiveadminJobs::Engine.root, "app", "admin")] 15 | 16 | class ActiveAdmin::Views::Pages::Base 17 | alias_method :adj_add_classes_to_body, :add_classes_to_body 18 | 19 | def add_classes_to_body 20 | adj_add_classes_to_body 21 | current_user_method = ActiveAdmin.application.current_user_method 22 | 23 | if current_user_method 24 | admins_job_identifier = send(current_user_method).job_identifier 25 | @body.set_attribute "data-identifier", admins_job_identifier 26 | @body.set_attribute "data-root-url", "/" 27 | @body.set_attribute "data-jobs-url", AdminHelpers.jobs_url 28 | @body.set_attribute "data-translations", I18nDictionary.translations.to_json 29 | end 30 | end 31 | end 32 | -------------------------------------------------------------------------------- /MIT-LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2016 Platanus 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining 4 | a copy of this software and associated documentation files (the 5 | "Software"), to deal in the Software without restriction, including 6 | without limitation the rights to use, copy, modify, merge, publish, 7 | distribute, sublicense, and/or sell copies of the Software, and to 8 | permit persons to whom the Software is furnished to do so, subject to 9 | the following conditions: 10 | 11 | The above copyright notice and this permission notice shall be 12 | included in all copies or substantial portions of the Software. 13 | 14 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, 15 | EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16 | MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND 17 | NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE 18 | LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION 19 | OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION 20 | WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 21 | -------------------------------------------------------------------------------- /spec/dummy/app/admin/admin_users.rb: -------------------------------------------------------------------------------- 1 | ActiveAdmin.register AdminUser do 2 | permit_params :email, :password, :password_confirmation 3 | 4 | index do 5 | selectable_column 6 | id_column 7 | column :email 8 | column :current_sign_in_at 9 | column :sign_in_count 10 | column :created_at 11 | actions 12 | end 13 | 14 | filter :email 15 | filter :current_sign_in_at 16 | filter :sign_in_count 17 | filter :created_at 18 | 19 | form do |f| 20 | f.inputs "Admin Details" do 21 | f.input :email 22 | f.input :password 23 | f.input :password_confirmation 24 | end 25 | f.actions 26 | end 27 | 28 | collection_action :import_form, title: "Import Users" do 29 | end 30 | 31 | action_item :import_users, only: :index do 32 | link_to "Import Users", import_form_admin_admin_users_path 33 | end 34 | 35 | collection_action :import, title: "Import Users", method: :post do 36 | UserUploadJob.perform_later(current_admin_user.job_identifier, [true, false].sample) 37 | redirect_to(import_form_admin_admin_users_path, 38 | notice: "The import process was started. We'll notify you when it's done.") 39 | end 40 | end 41 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: ruby 2 | rvm: 3 | - 2.3.1 4 | addons: 5 | chrome: stable 6 | before_install: 7 | - gem install bundler -v 1.12.5 8 | - wget http://chromedriver.storage.googleapis.com/2.36/chromedriver_linux64.zip 9 | - unzip chromedriver_linux64.zip 10 | - rm chromedriver_linux64.zip 11 | - sudo mv -f chromedriver /usr/local/bin/ 12 | - sudo chmod +x /usr/local/bin/chromedriver 13 | - google-chrome-stable --headless --no-sandbox 14 | script: 15 | - RAILS_ENV=test bundle exec rake db:create db:migrate 16 | - bundle exec rspec spec 17 | deploy: 18 | provider: rubygems 19 | api_key: 20 | secure: KWyxLcTNDKLaUjXelwyTNPtB/HcolK02mqrpJVwgA7OW6htXqMW+HBVcIizxzNNKouFgkfr3rqwthRNSRF0RtoEEeLihkx4VPGq7INe3hw8A5+urLchBFgzslYX/dMuoBazifXr4xTX2qeD53yjr2KBlPU8p8a0EhwPYjkcD12A/f9gNehyoLSRLALH6HCfBOJngqRsEdhsHGYuz8DHE5nb8B+4g+POmQlx8Yapm7Z/8axtXQNZk9yt3ZeujLr5AC8SeFEpTJlFc8yVffrTh6ALFznnYZ/H2DuNQWgjx1oEiKCBDYlKNmy6JJXB07LCpCcaaWLdezHsB/eMYY9M5WDGMhagzmavbhQzUtse/NvXgbpRDeW2ODREriPSOklMP830YIvqHrYqA/3kaz474ChZaSGRzeIEpMTcC6VjtDluzo+VhJkfo2pGQnACuoKXI0fCCtK++Nw9QGIem4k1ro4bjNDel7F+CfAlFDF+MCTKQBdg04gX6fcNKJptuvKtT9/DTC0hte2/ytzGVBw5qzSU9m1nAy52QzJUPldfB96h8CkwoM2oYZTIqdHG5/tbBFPNWjC1H3CgYJ/mGcH1Vs2pTIRXYGBbDdOR6UeIMEj4k8NwErW7xJJPCv9qQCatE5235I9aX/zRAHowUkmkvtHhHt33ItBkqfKPchluRlIY= 21 | gem: activeadmin_jobs 22 | on: 23 | tags: true 24 | repo: platanus/activeadmin_jobs 25 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20160612014504_create_delayed_jobs.rb: -------------------------------------------------------------------------------- 1 | class CreateDelayedJobs < ActiveRecord::Migration 2 | def self.up 3 | create_table :delayed_jobs, force: true do |table| 4 | table.integer :priority, default: 0, null: false # Allows some jobs to jump to the front of the queue 5 | table.integer :attempts, default: 0, null: false # Provides for retries, but still fail eventually. 6 | table.text :handler, null: false # YAML-encoded string of the object that will do work 7 | table.text :last_error # reason for last failure (See Note below) 8 | table.datetime :run_at # When to run. Could be Time.zone.now for immediately, or sometime in the future. 9 | table.datetime :locked_at # Set when a client is working on this object 10 | table.datetime :failed_at # Set when all retries have failed (actually, by default, the record is deleted instead) 11 | table.string :locked_by # Who is working on this object (if locked) 12 | table.string :queue # The name of the queue this job is in 13 | table.timestamps null: true 14 | end 15 | 16 | add_index :delayed_jobs, [:priority, :run_at], name: "delayed_jobs_priority" 17 | end 18 | 19 | def self.down 20 | drop_table :delayed_jobs 21 | end 22 | end 23 | -------------------------------------------------------------------------------- /spec/dummy/config/application.rb: -------------------------------------------------------------------------------- 1 | require File.expand_path('../boot', __FILE__) 2 | 3 | # Pick the frameworks you want: 4 | require "active_record/railtie" 5 | require "action_controller/railtie" 6 | require "action_mailer/railtie" 7 | require "action_view/railtie" 8 | require "sprockets/railtie" 9 | # require "rails/test_unit/railtie" 10 | 11 | Bundler.require(*Rails.groups) 12 | require "activeadmin_jobs" 13 | 14 | module Dummy 15 | class Application < Rails::Application 16 | # Settings in config/environments/* take precedence over those specified here. 17 | # Application configuration should go into files in config/initializers 18 | # -- all .rb files in that directory are automatically loaded. 19 | 20 | # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone. 21 | # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC. 22 | # config.time_zone = 'Central Time (US & Canada)' 23 | 24 | # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded. 25 | # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s] 26 | # config.i18n.default_locale = :de 27 | 28 | # Do not swallow errors in after_commit/after_rollback callbacks. 29 | config.active_record.raise_in_transactional_callbacks = true 30 | 31 | config.active_job.queue_adapter = :delayed_job 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /CHANGELOG.md: -------------------------------------------------------------------------------- 1 | # Change Log 2 | All notable changes to this project will be documented in this file. 3 | This project adheres to [Semantic Versioning](http://semver.org/). 4 | 5 | ### v0.5.2 6 | 7 | ##### Fixed 8 | 9 | - Demodulize job_class attribute to get the right path in js file too. 10 | 11 | ### v0.5.0 12 | 13 | ##### Added 14 | 15 | - Demodulize job_class attribute to get the right path. 16 | 17 | ### v0.4.1 18 | 19 | ##### Fixed 20 | 21 | - Avoid running ActiveAdmin.setup in the engine. This is causing a rare performance issue. 22 | 23 | ### v0.4.0 24 | 25 | ##### Changed 26 | 27 | - Change dependency versions to be more flexible. 28 | 29 | ##### Added 30 | 31 | - Add Hound configuration. 32 | - Deploy with Travis CI. 33 | 34 | ### v0.3.0 35 | 36 | ##### Added 37 | 38 | - Add Hound configuration. 39 | - Deploy with Travis CI. 40 | 41 | ### v0.2.1 42 | 43 | #### Fixed 44 | 45 | - Filter jobs by identifier. 46 | 47 | ### v0.2.0 48 | 49 | #### Added 50 | 51 | - Add .travis.yml with config to deploy on tag creation. 52 | 53 | #### Removed 54 | 55 | - Remove useless notified column from index/show job's views. 56 | 57 | #### Security 58 | 59 | - Avoid CSRF issue executing protect_from_forgery in Application Controller. 60 | 61 | ### v0.1.2 62 | 63 | #### Fixed 64 | 65 | - Run job_notifier installer from this gem's installer. 66 | 67 | ### v0.1.1 68 | 69 | #### Fixed 70 | 71 | - Remove unreachable growl gem from gemspec. 72 | 73 | ### v0.1.0 74 | 75 | - Initial release. 76 | -------------------------------------------------------------------------------- /spec/dummy/db/migrate/20160520161112_devise_create_admin_users.rb: -------------------------------------------------------------------------------- 1 | class DeviseCreateAdminUsers < ActiveRecord::Migration 2 | def change 3 | create_table(:admin_users) do |t| 4 | ## Database authenticatable 5 | t.string :email, null: false, default: "" 6 | t.string :encrypted_password, null: false, default: "" 7 | 8 | ## Recoverable 9 | t.string :reset_password_token 10 | t.datetime :reset_password_sent_at 11 | 12 | ## Rememberable 13 | t.datetime :remember_created_at 14 | 15 | ## Trackable 16 | t.integer :sign_in_count, default: 0, null: false 17 | t.datetime :current_sign_in_at 18 | t.datetime :last_sign_in_at 19 | t.string :current_sign_in_ip 20 | t.string :last_sign_in_ip 21 | 22 | ## Confirmable 23 | # t.string :confirmation_token 24 | # t.datetime :confirmed_at 25 | # t.datetime :confirmation_sent_at 26 | # t.string :unconfirmed_email # Only if using reconfirmable 27 | 28 | ## Lockable 29 | # t.integer :failed_attempts, default: 0, null: false # Only if lock strategy is :failed_attempts 30 | # t.string :unlock_token # Only if unlock strategy is :email or :both 31 | # t.datetime :locked_at 32 | 33 | 34 | t.timestamps null: false 35 | end 36 | 37 | add_index :admin_users, :email, unique: true 38 | add_index :admin_users, :reset_password_token, unique: true 39 | # add_index :admin_users, :confirmation_token, unique: true 40 | # add_index :admin_users, :unlock_token, unique: true 41 | end 42 | end 43 | -------------------------------------------------------------------------------- /activeadmin_jobs.gemspec: -------------------------------------------------------------------------------- 1 | $:.push File.expand_path("../lib", __FILE__) 2 | 3 | # Maintain your gem's version: 4 | require "activeadmin_jobs/version" 5 | 6 | # Describe your gem and declare its dependencies: 7 | Gem::Specification.new do |s| 8 | s.name = "activeadmin_jobs" 9 | s.version = ActiveadminJobs::VERSION 10 | s.authors = ["Platanus", "Emilio Blanco", "Leandro Segovia"] 11 | s.email = ["rubygems@platan.us", "emilioeduardob@gmail.com", "ldlsegovia@gmail.com"] 12 | s.homepage = "https://github.com/platanus/activeadmin_jobs" 13 | s.summary = "Gem that allows you to play nice with Active Job in Active Admin providing feedback" 14 | s.description = "It's a Rails engine that allows you to play nice with Active Job in Active Admin providing user feedback" 15 | s.license = "MIT" 16 | 17 | s.files = `git ls-files`.split($/).reject { |fn| fn.start_with? "spec" } 18 | 19 | s.add_dependency "rails", ">= 4.2" 20 | s.add_dependency "job_notifier", ">= 1.2.4" 21 | s.add_dependency "devise", ">= 3.5.0" 22 | s.add_dependency "activeadmin", ">= 1.0.0.pre2" 23 | s.add_dependency "activeadmin_addons", ">= 0.12.0" 24 | 25 | s.add_development_dependency "pry-rails" 26 | s.add_development_dependency "sqlite3" 27 | s.add_development_dependency "rspec-rails", ">= 3.4.0" 28 | s.add_development_dependency "capybara-selenium" 29 | s.add_development_dependency "database_cleaner" 30 | s.add_development_dependency "daemons" 31 | s.add_development_dependency "delayed_job_active_record" 32 | s.add_development_dependency "quiet_assets" 33 | s.add_development_dependency "jquery-ui-rails", ">= 5.0.5" 34 | end 35 | -------------------------------------------------------------------------------- /spec/dummy/public/500.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | We're sorry, but something went wrong (500) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

We're sorry, but something went wrong.

62 |
63 |

If you are the application owner check the logs for more information.

64 |
65 | 66 | 67 | -------------------------------------------------------------------------------- /spec/dummy/config/environments/development.rb: -------------------------------------------------------------------------------- 1 | Rails.application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # In the development environment your application's code is reloaded on 5 | # every request. This slows down response time but is perfect for development 6 | # since you don't have to restart the web server when you make code changes. 7 | config.cache_classes = false 8 | 9 | # Do not eager load code on boot. 10 | config.eager_load = false 11 | 12 | # Show full error reports and disable caching. 13 | config.consider_all_requests_local = true 14 | config.action_controller.perform_caching = false 15 | 16 | # Don't care if the mailer can't send. 17 | config.action_mailer.raise_delivery_errors = false 18 | 19 | # Print deprecation notices to the Rails logger. 20 | config.active_support.deprecation = :log 21 | 22 | # Raise an error on page load if there are pending migrations. 23 | config.active_record.migration_error = :page_load 24 | 25 | # Debug mode disables concatenation and preprocessing of assets. 26 | # This option may cause significant delays in view rendering with a large 27 | # number of complex assets. 28 | config.assets.debug = true 29 | 30 | # Asset digests allow you to set far-future HTTP expiration dates on all assets, 31 | # yet still be able to expire them through the digest params. 32 | config.assets.digest = true 33 | 34 | # Adds additional error checking when serving assets at runtime. 35 | # Checks for improperly declared sprockets dependencies. 36 | # Raises helpful error messages. 37 | config.assets.raise_runtime_errors = true 38 | 39 | # Raises error for missing translations 40 | # config.action_view.raise_on_missing_translations = true 41 | end 42 | -------------------------------------------------------------------------------- /spec/dummy/public/422.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The change you wanted was rejected (422) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

The change you wanted was rejected.

62 |

Maybe you tried to change something you didn't have access to.

63 |
64 |

If you are the application owner check the logs for more information.

65 |
66 | 67 | 68 | -------------------------------------------------------------------------------- /spec/dummy/public/404.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | The page you were looking for doesn't exist (404) 5 | 6 | 55 | 56 | 57 | 58 | 59 |
60 |
61 |

The page you were looking for doesn't exist.

62 |

You may have mistyped the address or the page may have moved.

63 |
64 |

If you are the application owner check the logs for more information.

65 |
66 | 67 | 68 | -------------------------------------------------------------------------------- /spec/dummy/config/environments/test.rb: -------------------------------------------------------------------------------- 1 | Rails.application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # The test environment is used exclusively to run your application's 5 | # test suite. You never need to work with it otherwise. Remember that 6 | # your test database is "scratch space" for the test suite and is wiped 7 | # and recreated between test runs. Don't rely on the data there! 8 | config.cache_classes = true 9 | 10 | # Do not eager load code on boot. This avoids loading your whole application 11 | # just for the purpose of running a single test. If you are using a tool that 12 | # preloads Rails for running tests, you may have to set it to true. 13 | config.eager_load = false 14 | 15 | # Configure static file server for tests with Cache-Control for performance. 16 | config.serve_static_files = true 17 | config.static_cache_control = 'public, max-age=3600' 18 | 19 | # Show full error reports and disable caching. 20 | config.consider_all_requests_local = true 21 | config.action_controller.perform_caching = false 22 | 23 | # Raise exceptions instead of rendering exception templates. 24 | config.action_dispatch.show_exceptions = false 25 | 26 | # Disable request forgery protection in test environment. 27 | config.action_controller.allow_forgery_protection = false 28 | 29 | # Tell Action Mailer not to deliver emails to the real world. 30 | # The :test delivery method accumulates sent emails in the 31 | # ActionMailer::Base.deliveries array. 32 | config.action_mailer.delivery_method = :test 33 | 34 | # Randomize the order test cases are executed. 35 | config.active_support.test_order = :random 36 | 37 | # Print deprecation notices to the stderr. 38 | config.active_support.deprecation = :stderr 39 | 40 | # Raises error for missing translations 41 | # config.action_view.raise_on_missing_translations = true 42 | end 43 | -------------------------------------------------------------------------------- /spec/features/job_show_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | describe "Job index", type: :feature do 4 | context "index view" do 5 | before { @admin = login_admin_user } 6 | 7 | context "with job without result" do 8 | before do 9 | @job = create_job(identifier: @admin.job_identifier, result: nil, notified: false) 10 | visit admin_job_path(@job) 11 | end 12 | 13 | it "shows id row" do 14 | row = find_row(:id, nil) 15 | expect(row.text).to eq(@job.id.to_s) 16 | end 17 | 18 | it "shows status row" do 19 | row = find_row(:status) 20 | expect(row[:class]).to eq("status_tag pending") 21 | expect(row.text).to eq("Pending") 22 | end 23 | 24 | it "shows created at row" do 25 | col = find_row(:created_at, nil) 26 | expect(col.text).to eq(I18n.l(@job.created_at, format: :long)) 27 | end 28 | 29 | it "hides result panel" do 30 | expect { find_panel("Result") }.to raise_error(Capybara::ElementNotFound) 31 | end 32 | end 33 | 34 | context "with job with result" do 35 | before { @job = create_job(identifier: @admin.job_identifier, result: "result") } 36 | 37 | context "with finished status" do 38 | before do 39 | @job.update_column(:status, "finished") 40 | visit admin_job_path(@job) 41 | @panel = find_panel("Result", true) 42 | end 43 | 44 | it "renders finished view" do 45 | expect(@panel.text).to eq("Finished result") 46 | end 47 | end 48 | 49 | context "with failed status" do 50 | before do 51 | @job.update_column(:status, "failed") 52 | visit admin_job_path(@job) 53 | @panel = find_panel("Result", true) 54 | end 55 | 56 | it "renders failed view" do 57 | expect(@panel.text).to eq("Failed result") 58 | end 59 | end 60 | end 61 | end 62 | end 63 | -------------------------------------------------------------------------------- /spec/support/capybara_helpers.rb: -------------------------------------------------------------------------------- 1 | require "capybara/rspec" 2 | require "capybara/rails" 3 | require "selenium-webdriver" 4 | 5 | module CapybaraHelpers 6 | def find_column(attribute, tag = nil) 7 | inner_tag = case attribute 8 | when :id then "a" 9 | when :created_at then nil 10 | else "span" 11 | end 12 | 13 | inner_tag = tag if tag 14 | col = find("td[class=\"col col-#{attribute}\"]") 15 | col = col.find(inner_tag) if inner_tag 16 | col 17 | end 18 | 19 | def find_row(attribute, tag = "span") 20 | row = find("tr[class=\"row row-#{attribute}\"]").find("td") 21 | row = row.find(tag) if tag 22 | row 23 | end 24 | 25 | def find_panel(title, content = false) 26 | panel = find("h3", text: title).find(:xpath, "..") 27 | return panel unless content 28 | panel.find("div[class=\"panel_contents\"]") 29 | end 30 | 31 | def notification(pos = 1) 32 | find(".growl:nth-of-type(#{pos})") 33 | end 34 | 35 | def notification_title(pos = 1) 36 | notification(pos).find(".growl-title") 37 | end 38 | 39 | def notification_link(pos = 1) 40 | notification(pos).find(".growl-message").find("a") 41 | end 42 | 43 | def create_job(identifier: nil, status: nil, result: nil, notified: nil) 44 | data = { 45 | identifier: identifier || SecureRandom.hex, 46 | job_id: 1, 47 | job_class: "JobTest", 48 | status: status || "pending", 49 | result: result, 50 | notified: notified.nil? ? [true, false].sample : notified 51 | } 52 | 53 | @job = JobNotifier::Job.create!(data) 54 | end 55 | end 56 | 57 | RSpec.configure do |config| 58 | Capybara.register_driver :chrome do |app| 59 | Capybara::Selenium::Driver.new(app, browser: :chrome) 60 | end 61 | 62 | Capybara.register_driver :headless_chrome do |app| 63 | capabilities = Selenium::WebDriver::Remote::Capabilities.chrome( 64 | chromeOptions: { args: %w(headless) } 65 | ) 66 | Capybara::Selenium::Driver.new(app, browser: :chrome, desired_capabilities: capabilities) 67 | end 68 | 69 | # change to :chrome if you want to see the browser running. 70 | Capybara.javascript_driver = :headless_chrome 71 | 72 | config.include CapybaraHelpers 73 | end 74 | -------------------------------------------------------------------------------- /spec/features/notifications_spec.rb: -------------------------------------------------------------------------------- 1 | require "rails_helper" 2 | 3 | describe "Notifications", type: :feature do 4 | before(:all) do 5 | # Give more time to notifications 6 | @old_default_max_wait_time = Capybara.default_max_wait_time 7 | Capybara.default_max_wait_time = 15 8 | end 9 | 10 | after(:all) do 11 | # Restore default 12 | Capybara.default_max_wait_time = @old_default_max_wait_time 13 | end 14 | 15 | before { @admin = login_admin_user } 16 | 17 | context "with one finished job" do 18 | before do 19 | create_job(identifier: @admin.job_identifier, notified: false, status: "finished") 20 | visit admin_jobs_path 21 | end 22 | 23 | it "shows finished notification", js: true do 24 | expect(notification_title.text).to eq("Finished Job!") 25 | expect(notification_link.text).to eq("the job was completed! :)") 26 | notification_link.click 27 | expect(find_row(:status).text).to eq("FINISHED") 28 | end 29 | end 30 | 31 | context "with one failed job" do 32 | before do 33 | create_job(identifier: @admin.job_identifier, notified: false, status: "failed") 34 | visit admin_jobs_path 35 | end 36 | 37 | it "shows failed notification", js: true do 38 | expect(notification_title.text).to eq("Failed Job") 39 | expect(notification_link.text).to eq("the job was not completed :(") 40 | notification_link.click 41 | expect(find_row(:status).text).to eq("FAILED") 42 | end 43 | end 44 | 45 | context "with multiple jobs" do 46 | before do 47 | 2.times { create_job(identifier: @admin.job_identifier, notified: false, status: "finished") } 48 | job = create_job(identifier: @admin.job_identifier, notified: false, status: "failed") 49 | visit admin_job_path(job) 50 | end 51 | 52 | it "shows multiple notifications", js: true do 53 | expect(notification_title(1).text).to eq("Finished Job!") 54 | expect(notification_title(2).text).to eq("Failed Job") 55 | 56 | expect(notification_link(1).text).to eq("2 jobs were completed! :)") 57 | expect(notification_link(2).text).to eq("the job was not completed :(") 58 | 59 | notification_link(1).click 60 | expect(page).to have_content "Displaying all 3 Jobs" 61 | end 62 | end 63 | end 64 | -------------------------------------------------------------------------------- /spec/dummy/config/environments/production.rb: -------------------------------------------------------------------------------- 1 | Rails.application.configure do 2 | # Settings specified here will take precedence over those in config/application.rb. 3 | 4 | # Code is not reloaded between requests. 5 | config.cache_classes = true 6 | 7 | # Eager load code on boot. This eager loads most of Rails and 8 | # your application in memory, allowing both threaded web servers 9 | # and those relying on copy on write to perform better. 10 | # Rake tasks automatically ignore this option for performance. 11 | config.eager_load = true 12 | 13 | # Full error reports are disabled and caching is turned on. 14 | config.consider_all_requests_local = false 15 | config.action_controller.perform_caching = true 16 | 17 | # Enable Rack::Cache to put a simple HTTP cache in front of your application 18 | # Add `rack-cache` to your Gemfile before enabling this. 19 | # For large-scale production use, consider using a caching reverse proxy like 20 | # NGINX, varnish or squid. 21 | # config.action_dispatch.rack_cache = true 22 | 23 | # Disable serving static files from the `/public` folder by default since 24 | # Apache or NGINX already handles this. 25 | config.serve_static_files = ENV['RAILS_SERVE_STATIC_FILES'].present? 26 | 27 | # Compress JavaScripts and CSS. 28 | config.assets.js_compressor = :uglifier 29 | # config.assets.css_compressor = :sass 30 | 31 | # Do not fallback to assets pipeline if a precompiled asset is missed. 32 | config.assets.compile = false 33 | 34 | # Asset digests allow you to set far-future HTTP expiration dates on all assets, 35 | # yet still be able to expire them through the digest params. 36 | config.assets.digest = true 37 | 38 | # `config.assets.precompile` and `config.assets.version` have moved to config/initializers/assets.rb 39 | 40 | # Specifies the header that your server uses for sending files. 41 | # config.action_dispatch.x_sendfile_header = 'X-Sendfile' # for Apache 42 | # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for NGINX 43 | 44 | # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies. 45 | # config.force_ssl = true 46 | 47 | # Use the lowest log level to ensure availability of diagnostic information 48 | # when problems arise. 49 | config.log_level = :debug 50 | 51 | # Prepend all log lines with the following tags. 52 | # config.log_tags = [ :subdomain, :uuid ] 53 | 54 | # Use a different logger for distributed setups. 55 | # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new) 56 | 57 | # Use a different cache store in production. 58 | # config.cache_store = :mem_cache_store 59 | 60 | # Enable serving of images, stylesheets, and JavaScripts from an asset server. 61 | # config.action_controller.asset_host = 'http://assets.example.com' 62 | 63 | # Ignore bad email addresses and do not raise email delivery errors. 64 | # Set this to true and configure the email server for immediate delivery to raise delivery errors. 65 | # config.action_mailer.raise_delivery_errors = false 66 | 67 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to 68 | # the I18n.default_locale when a translation cannot be found). 69 | config.i18n.fallbacks = true 70 | 71 | # Send deprecation notices to registered listeners. 72 | config.active_support.deprecation = :notify 73 | 74 | # Use default logging formatter so that PID and timestamp are not suppressed. 75 | config.log_formatter = ::Logger::Formatter.new 76 | 77 | # Do not dump schema after migrations. 78 | config.active_record.dump_schema_after_migration = false 79 | end 80 | -------------------------------------------------------------------------------- /app/assets/javascripts/activeadmin_jobs/growl_setup.js: -------------------------------------------------------------------------------- 1 | JobNotifier.onNotify = function(result) { 2 | DEFAULT_MESSAGES = { 3 | finished: { 4 | title: 'Completed Job', 5 | one: '1 job was successfully completed!', 6 | other: 'jobs were successfully completed!' 7 | }, 8 | failed: { 9 | title: 'Failed Job', 10 | one: '1 job was completed, but it contains errors...', 11 | other: 'jobs were completed, but they contains errors...' 12 | } 13 | }; 14 | 15 | function findTranslation(jobClass, status, key) { 16 | try { 17 | var translations = getTranslations(); 18 | return translations[jobClass][status][key]; 19 | } catch(err) { 20 | console.info('Translation not found. Using default...', jobClass, status, key); 21 | } 22 | 23 | return DEFAULT_MESSAGES[status][key]; 24 | } 25 | 26 | function camelToDash(str) { 27 | var parts = str.split('::'); 28 | str = parts[parts.length - 1].replace(/\W+/g, '_'); 29 | return str.replace(/([a-z\d])([A-Z])/g, '$1_$2').toLowerCase(); 30 | } 31 | 32 | function getTranslations() { 33 | var body = document.querySelector('body'); 34 | return JSON.parse(body.dataset.translations); 35 | } 36 | 37 | function getJobsUrl() { 38 | var body = document.querySelector('body'); 39 | return body.dataset.jobsUrl; 40 | } 41 | 42 | function prepareMessage(job, count) { 43 | var jobClass = camelToDash(job.job_class); 44 | var jobsUrl = getJobsUrl(); 45 | var msg = ''; 46 | 47 | if(count == 1) { 48 | jobsUrl += '/' + job.id; 49 | msg = findTranslation(jobClass, job.status, 'one'); 50 | } else { 51 | msg = count + ' ' + findTranslation(jobClass, job.status, 'other'); 52 | } 53 | 54 | var link = '' + msg + ''; 55 | 56 | return { 57 | title: findTranslation(jobClass, job.status, 'title'), 58 | message: link, 59 | duration: 6000 60 | }; 61 | } 62 | 63 | function showPopUp(job, count) { 64 | var msg = prepareMessage(job, count); 65 | 66 | switch(job.status) { 67 | case 'finished': 68 | $.growl.notice(msg); 69 | break; 70 | case 'failed': 71 | $.growl.error(msg); 72 | break; 73 | default: 74 | console.error('Invalid job status given', job.status); 75 | } 76 | } 77 | 78 | function groupJobsByClass(jobs) { 79 | var groupedJobs = {}; 80 | 81 | for(i = 0; i < jobs.length; i++) { 82 | var job = jobs[i]; 83 | 84 | if(job.status == 'pending') { 85 | continue; 86 | } 87 | 88 | var jobClass = camelToDash(job.job_class); 89 | 90 | if(!groupedJobs[jobClass]) { 91 | groupedJobs[jobClass] = {}; 92 | } 93 | 94 | if(!groupedJobs[jobClass][job.status]) { 95 | groupedJobs[jobClass][job.status] = []; 96 | } 97 | 98 | groupedJobs[jobClass][job.status].push(job); 99 | } 100 | 101 | return groupedJobs; 102 | } 103 | 104 | function showMsg(jobs) { 105 | if(jobs.length === 0) { 106 | return; 107 | } 108 | 109 | var groupedJobs = groupJobsByClass(jobs); 110 | 111 | for(var jobClass in groupedJobs) { 112 | if(groupedJobs.hasOwnProperty(jobClass)) { 113 | for(var status in groupedJobs[jobClass]) { 114 | if(groupedJobs[jobClass].hasOwnProperty(status)) { 115 | jobs = groupedJobs[jobClass][status]; 116 | showPopUp(jobs[0], jobs.length); 117 | } 118 | } 119 | } 120 | } 121 | } 122 | 123 | showMsg(result); 124 | }; 125 | -------------------------------------------------------------------------------- /spec/dummy/db/schema.rb: -------------------------------------------------------------------------------- 1 | # encoding: UTF-8 2 | # This file is auto-generated from the current state of the database. Instead 3 | # of editing this file, please use the migrations feature of Active Record to 4 | # incrementally modify your database, and then regenerate this schema definition. 5 | # 6 | # Note that this schema.rb definition is the authoritative source for your 7 | # database schema. If you need to create the application database on another 8 | # system, you should be using db:schema:load, not running all the migrations 9 | # from scratch. The latter is a flawed and unsustainable approach (the more migrations 10 | # you'll amass, the slower it'll run and the greater likelihood for issues). 11 | # 12 | # It's strongly recommended that you check this file into your version control system. 13 | 14 | ActiveRecord::Schema.define(version: 20160612014504) do 15 | 16 | create_table "active_admin_comments", force: :cascade do |t| 17 | t.string "namespace" 18 | t.text "body" 19 | t.string "resource_id", null: false 20 | t.string "resource_type", null: false 21 | t.integer "author_id" 22 | t.string "author_type" 23 | t.datetime "created_at" 24 | t.datetime "updated_at" 25 | end 26 | 27 | add_index "active_admin_comments", ["author_type", "author_id"], name: "index_active_admin_comments_on_author_type_and_author_id" 28 | add_index "active_admin_comments", ["namespace"], name: "index_active_admin_comments_on_namespace" 29 | add_index "active_admin_comments", ["resource_type", "resource_id"], name: "index_active_admin_comments_on_resource_type_and_resource_id" 30 | 31 | create_table "admin_users", force: :cascade do |t| 32 | t.string "email", default: "", null: false 33 | t.string "encrypted_password", default: "", null: false 34 | t.string "reset_password_token" 35 | t.datetime "reset_password_sent_at" 36 | t.datetime "remember_created_at" 37 | t.integer "sign_in_count", default: 0, null: false 38 | t.datetime "current_sign_in_at" 39 | t.datetime "last_sign_in_at" 40 | t.string "current_sign_in_ip" 41 | t.string "last_sign_in_ip" 42 | t.datetime "created_at", null: false 43 | t.datetime "updated_at", null: false 44 | end 45 | 46 | add_index "admin_users", ["email"], name: "index_admin_users_on_email", unique: true 47 | add_index "admin_users", ["reset_password_token"], name: "index_admin_users_on_reset_password_token", unique: true 48 | 49 | create_table "delayed_jobs", force: :cascade do |t| 50 | t.integer "priority", default: 0, null: false 51 | t.integer "attempts", default: 0, null: false 52 | t.text "handler", null: false 53 | t.text "last_error" 54 | t.datetime "run_at" 55 | t.datetime "locked_at" 56 | t.datetime "failed_at" 57 | t.string "locked_by" 58 | t.string "queue" 59 | t.datetime "created_at" 60 | t.datetime "updated_at" 61 | end 62 | 63 | add_index "delayed_jobs", ["priority", "run_at"], name: "delayed_jobs_priority" 64 | 65 | create_table "job_notifier_jobs", force: :cascade do |t| 66 | t.string "identifier" 67 | t.string "job_id" 68 | t.string "job_class" 69 | t.string "status" 70 | t.text "result" 71 | t.boolean "notified", default: false 72 | t.datetime "created_at", null: false 73 | t.datetime "updated_at", null: false 74 | end 75 | 76 | add_index "job_notifier_jobs", ["identifier"], name: "index_job_notifier_jobs_on_identifier" 77 | add_index "job_notifier_jobs", ["job_id"], name: "index_job_notifier_jobs_on_job_id" 78 | 79 | end 80 | -------------------------------------------------------------------------------- /spec/dummy/config/locales/devise.en.yml: -------------------------------------------------------------------------------- 1 | # Additional translations at https://github.com/plataformatec/devise/wiki/I18n 2 | 3 | en: 4 | devise: 5 | confirmations: 6 | confirmed: "Your email address has been successfully confirmed." 7 | send_instructions: "You will receive an email with instructions for how to confirm your email address in a few minutes." 8 | send_paranoid_instructions: "If your email address exists in our database, you will receive an email with instructions for how to confirm your email address in a few minutes." 9 | failure: 10 | already_authenticated: "You are already signed in." 11 | inactive: "Your account is not activated yet." 12 | invalid: "Invalid %{authentication_keys} or password." 13 | locked: "Your account is locked." 14 | last_attempt: "You have one more attempt before your account is locked." 15 | not_found_in_database: "Invalid %{authentication_keys} or password." 16 | timeout: "Your session expired. Please sign in again to continue." 17 | unauthenticated: "You need to sign in or sign up before continuing." 18 | unconfirmed: "You have to confirm your email address before continuing." 19 | mailer: 20 | confirmation_instructions: 21 | subject: "Confirmation instructions" 22 | reset_password_instructions: 23 | subject: "Reset password instructions" 24 | unlock_instructions: 25 | subject: "Unlock instructions" 26 | password_change: 27 | subject: "Password Changed" 28 | omniauth_callbacks: 29 | failure: "Could not authenticate you from %{kind} because \"%{reason}\"." 30 | success: "Successfully authenticated from %{kind} account." 31 | passwords: 32 | no_token: "You can't access this page without coming from a password reset email. If you do come from a password reset email, please make sure you used the full URL provided." 33 | send_instructions: "You will receive an email with instructions on how to reset your password in a few minutes." 34 | send_paranoid_instructions: "If your email address exists in our database, you will receive a password recovery link at your email address in a few minutes." 35 | updated: "Your password has been changed successfully. You are now signed in." 36 | updated_not_active: "Your password has been changed successfully." 37 | registrations: 38 | destroyed: "Bye! Your account has been successfully cancelled. We hope to see you again soon." 39 | signed_up: "Welcome! You have signed up successfully." 40 | signed_up_but_inactive: "You have signed up successfully. However, we could not sign you in because your account is not yet activated." 41 | signed_up_but_locked: "You have signed up successfully. However, we could not sign you in because your account is locked." 42 | signed_up_but_unconfirmed: "A message with a confirmation link has been sent to your email address. Please follow the link to activate your account." 43 | update_needs_confirmation: "You updated your account successfully, but we need to verify your new email address. Please check your email and follow the confirm link to confirm your new email address." 44 | updated: "Your account has been updated successfully." 45 | sessions: 46 | signed_in: "Signed in successfully." 47 | signed_out: "Signed out successfully." 48 | already_signed_out: "Signed out successfully." 49 | unlocks: 50 | send_instructions: "You will receive an email with instructions for how to unlock your account in a few minutes." 51 | send_paranoid_instructions: "If your account exists, you will receive an email with instructions for how to unlock it in a few minutes." 52 | unlocked: "Your account has been unlocked successfully. Please sign in to continue." 53 | errors: 54 | messages: 55 | already_confirmed: "was already confirmed, please try signing in" 56 | confirmation_period_expired: "needs to be confirmed within %{period}, please request a new one" 57 | expired: "has expired, please request a new one" 58 | not_found: "not found" 59 | not_locked: "was not locked" 60 | not_saved: 61 | one: "1 error prohibited this %{resource} from being saved:" 62 | other: "%{count} errors prohibited this %{resource} from being saved:" 63 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: . 3 | specs: 4 | activeadmin_jobs (0.5.2) 5 | activeadmin (>= 1.0.0.pre2) 6 | activeadmin_addons (>= 0.12.0) 7 | devise (>= 3.5.0) 8 | job_notifier (>= 1.2.4) 9 | rails (>= 4.2) 10 | 11 | GEM 12 | remote: https://rubygems.org/ 13 | remote: https://rails-assets.org/ 14 | specs: 15 | actionmailer (4.2.10) 16 | actionpack (= 4.2.10) 17 | actionview (= 4.2.10) 18 | activejob (= 4.2.10) 19 | mail (~> 2.5, >= 2.5.4) 20 | rails-dom-testing (~> 1.0, >= 1.0.5) 21 | actionpack (4.2.10) 22 | actionview (= 4.2.10) 23 | activesupport (= 4.2.10) 24 | rack (~> 1.6) 25 | rack-test (~> 0.6.2) 26 | rails-dom-testing (~> 1.0, >= 1.0.5) 27 | rails-html-sanitizer (~> 1.0, >= 1.0.2) 28 | actionview (4.2.10) 29 | activesupport (= 4.2.10) 30 | builder (~> 3.1) 31 | erubis (~> 2.7.0) 32 | rails-dom-testing (~> 1.0, >= 1.0.5) 33 | rails-html-sanitizer (~> 1.0, >= 1.0.3) 34 | activeadmin (1.2.1) 35 | arbre (>= 1.1.1) 36 | coffee-rails 37 | formtastic (~> 3.1) 38 | formtastic_i18n 39 | inherited_resources (~> 1.7) 40 | jquery-rails (>= 4.2.0) 41 | kaminari (>= 0.15, < 2.0) 42 | railties (>= 4.2, < 5.2) 43 | ransack (~> 1.3) 44 | sass (~> 3.1) 45 | sprockets (< 4.1) 46 | activeadmin_addons (1.2.0) 47 | railties 48 | require_all 49 | select2-rails (~> 4.0) 50 | xdan-datetimepicker-rails (~> 2.5.1) 51 | activejob (4.2.10) 52 | activesupport (= 4.2.10) 53 | globalid (>= 0.3.0) 54 | activemodel (4.2.10) 55 | activesupport (= 4.2.10) 56 | builder (~> 3.1) 57 | activerecord (4.2.10) 58 | activemodel (= 4.2.10) 59 | activesupport (= 4.2.10) 60 | arel (~> 6.0) 61 | activesupport (4.2.10) 62 | i18n (~> 0.7) 63 | minitest (~> 5.1) 64 | thread_safe (~> 0.3, >= 0.3.4) 65 | tzinfo (~> 1.1) 66 | addressable (2.5.2) 67 | public_suffix (>= 2.0.2, < 4.0) 68 | arbre (1.1.1) 69 | activesupport (>= 3.0.0) 70 | arel (6.0.4) 71 | bcrypt (3.1.11) 72 | builder (3.2.3) 73 | capybara (2.18.0) 74 | addressable 75 | mini_mime (>= 0.1.3) 76 | nokogiri (>= 1.3.3) 77 | rack (>= 1.0.0) 78 | rack-test (>= 0.5.4) 79 | xpath (>= 2.0, < 4.0) 80 | capybara-selenium (0.0.6) 81 | capybara 82 | selenium-webdriver 83 | childprocess (0.9.0) 84 | ffi (~> 1.0, >= 1.0.11) 85 | coderay (1.1.1) 86 | coffee-rails (4.2.2) 87 | coffee-script (>= 2.2.0) 88 | railties (>= 4.0.0) 89 | coffee-script (2.4.1) 90 | coffee-script-source 91 | execjs 92 | coffee-script-source (1.12.2) 93 | colorize (0.8.1) 94 | concurrent-ruby (1.0.5) 95 | crass (1.0.3) 96 | daemons (1.2.3) 97 | database_cleaner (1.5.3) 98 | delayed_job (4.1.2) 99 | activesupport (>= 3.0, < 5.1) 100 | delayed_job_active_record (4.1.1) 101 | activerecord (>= 3.0, < 5.1) 102 | delayed_job (>= 3.0, < 5) 103 | devise (4.4.1) 104 | bcrypt (~> 3.0) 105 | orm_adapter (~> 0.1) 106 | railties (>= 4.1.0, < 5.2) 107 | responders 108 | warden (~> 1.2.3) 109 | diff-lcs (1.2.5) 110 | enumerize (2.1.2) 111 | activesupport (>= 3.2) 112 | erubis (2.7.0) 113 | execjs (2.7.0) 114 | ffi (1.9.10) 115 | formtastic (3.1.5) 116 | actionpack (>= 3.2.13) 117 | formtastic_i18n (0.6.0) 118 | globalid (0.4.1) 119 | activesupport (>= 4.2.0) 120 | has_scope (0.7.1) 121 | actionpack (>= 4.1, < 5.2) 122 | activesupport (>= 4.1, < 5.2) 123 | i18n (0.9.5) 124 | concurrent-ruby (~> 1.0) 125 | inherited_resources (1.8.0) 126 | actionpack (>= 4.2, <= 5.2) 127 | has_scope (~> 0.6) 128 | railties (>= 4.2, <= 5.2) 129 | responders 130 | job_notifier (1.3.0) 131 | colorize (>= 0.7.7) 132 | enumerize (>= 1.0) 133 | rails (>= 4.2.0) 134 | silencer (= 1.0.0.rc3) 135 | jquery-rails (4.3.1) 136 | rails-dom-testing (>= 1, < 3) 137 | railties (>= 4.2.0) 138 | thor (>= 0.14, < 2.0) 139 | jquery-ui-rails (5.0.5) 140 | railties (>= 3.2.16) 141 | kaminari (1.1.1) 142 | activesupport (>= 4.1.0) 143 | kaminari-actionview (= 1.1.1) 144 | kaminari-activerecord (= 1.1.1) 145 | kaminari-core (= 1.1.1) 146 | kaminari-actionview (1.1.1) 147 | actionview 148 | kaminari-core (= 1.1.1) 149 | kaminari-activerecord (1.1.1) 150 | activerecord 151 | kaminari-core (= 1.1.1) 152 | kaminari-core (1.1.1) 153 | loofah (2.2.2) 154 | crass (~> 1.0.2) 155 | nokogiri (>= 1.5.9) 156 | mail (2.7.0) 157 | mini_mime (>= 0.1.1) 158 | method_source (0.8.2) 159 | mini_mime (1.0.0) 160 | mini_portile2 (2.3.0) 161 | minitest (5.11.3) 162 | nokogiri (1.8.2) 163 | mini_portile2 (~> 2.3.0) 164 | orm_adapter (0.5.0) 165 | polyamorous (1.3.3) 166 | activerecord (>= 3.0) 167 | pry (0.10.3) 168 | coderay (~> 1.1.0) 169 | method_source (~> 0.8.1) 170 | slop (~> 3.4) 171 | pry-rails (0.3.4) 172 | pry (>= 0.9.10) 173 | public_suffix (3.0.2) 174 | quiet_assets (1.1.0) 175 | railties (>= 3.1, < 5.0) 176 | rack (1.6.9) 177 | rack-test (0.6.3) 178 | rack (>= 1.0) 179 | rails (4.2.10) 180 | actionmailer (= 4.2.10) 181 | actionpack (= 4.2.10) 182 | actionview (= 4.2.10) 183 | activejob (= 4.2.10) 184 | activemodel (= 4.2.10) 185 | activerecord (= 4.2.10) 186 | activesupport (= 4.2.10) 187 | bundler (>= 1.3.0, < 2.0) 188 | railties (= 4.2.10) 189 | sprockets-rails 190 | rails-assets-growl (1.3.1) 191 | rails-assets-jquery 192 | rails-assets-jquery (3.0.0) 193 | rails-deprecated_sanitizer (1.0.3) 194 | activesupport (>= 4.2.0.alpha) 195 | rails-dom-testing (1.0.9) 196 | activesupport (>= 4.2.0, < 5.0) 197 | nokogiri (~> 1.6) 198 | rails-deprecated_sanitizer (>= 1.0.1) 199 | rails-html-sanitizer (1.0.4) 200 | loofah (~> 2.2, >= 2.2.2) 201 | railties (4.2.10) 202 | actionpack (= 4.2.10) 203 | activesupport (= 4.2.10) 204 | rake (>= 0.8.7) 205 | thor (>= 0.18.1, < 2.0) 206 | rake (12.3.1) 207 | ransack (1.8.6) 208 | actionpack (>= 3.0) 209 | activerecord (>= 3.0) 210 | activesupport (>= 3.0) 211 | i18n 212 | polyamorous (~> 1.3.2) 213 | rb-fsevent (0.10.2) 214 | rb-inotify (0.9.10) 215 | ffi (>= 0.5.0, < 2) 216 | require_all (1.5.0) 217 | responders (2.4.0) 218 | actionpack (>= 4.2.0, < 5.3) 219 | railties (>= 4.2.0, < 5.3) 220 | rspec-core (3.4.4) 221 | rspec-support (~> 3.4.0) 222 | rspec-expectations (3.4.0) 223 | diff-lcs (>= 1.2.0, < 2.0) 224 | rspec-support (~> 3.4.0) 225 | rspec-mocks (3.4.1) 226 | diff-lcs (>= 1.2.0, < 2.0) 227 | rspec-support (~> 3.4.0) 228 | rspec-rails (3.4.2) 229 | actionpack (>= 3.0, < 4.3) 230 | activesupport (>= 3.0, < 4.3) 231 | railties (>= 3.0, < 4.3) 232 | rspec-core (~> 3.4.0) 233 | rspec-expectations (~> 3.4.0) 234 | rspec-mocks (~> 3.4.0) 235 | rspec-support (~> 3.4.0) 236 | rspec-support (3.4.1) 237 | rubyzip (1.2.1) 238 | sass (3.5.5) 239 | sass-listen (~> 4.0.0) 240 | sass-listen (4.0.0) 241 | rb-fsevent (~> 0.9, >= 0.9.4) 242 | rb-inotify (~> 0.9, >= 0.9.7) 243 | select2-rails (4.0.3) 244 | thor (~> 0.14) 245 | selenium-webdriver (3.11.0) 246 | childprocess (~> 0.5) 247 | rubyzip (~> 1.2) 248 | silencer (1.0.0.rc3) 249 | slop (3.6.0) 250 | sprockets (3.7.1) 251 | concurrent-ruby (~> 1.0) 252 | rack (> 1, < 3) 253 | sprockets-rails (3.2.1) 254 | actionpack (>= 4.0) 255 | activesupport (>= 4.0) 256 | sprockets (>= 3.0.0) 257 | sqlite3 (1.3.11) 258 | thor (0.20.0) 259 | thread_safe (0.3.6) 260 | tzinfo (1.2.5) 261 | thread_safe (~> 0.1) 262 | warden (1.2.7) 263 | rack (>= 1.0) 264 | xdan-datetimepicker-rails (2.5.4) 265 | jquery-rails 266 | rails (>= 3.2.16) 267 | xpath (3.0.0) 268 | nokogiri (~> 1.8) 269 | 270 | PLATFORMS 271 | ruby 272 | 273 | DEPENDENCIES 274 | activeadmin_jobs! 275 | capybara-selenium 276 | daemons 277 | database_cleaner 278 | delayed_job_active_record 279 | jquery-ui-rails (>= 5.0.5) 280 | pry-rails 281 | quiet_assets 282 | rails-assets-growl (~> 1.3.1)! 283 | rspec-rails (>= 3.4.0) 284 | sqlite3 285 | 286 | BUNDLED WITH 287 | 1.16.1 288 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Active Admin Jobs 2 | [![Gem Version](https://badge.fury.io/rb/activeadmin_jobs.svg)](https://badge.fury.io/rb/activeadmin_jobs) 3 | [![Build Status](https://secure.travis-ci.org/platanus/activeadmin_jobs.svg?branch=master)](http://travis-ci.org/platanus/activeadmin_jobs) 4 | 5 | It's a Rails engine that allows you to play nice with [Active Job](https://github.com/rails/activejob) in [Active Admin](https://github.com/activeadmin/activeadmin) providing user feedback. 6 | 7 | - An Active Admin's index view to list jobs. 8 | - An Active Admin's show view to see job details with a special panel to show success/error feedback. To achieve this we are going to use the [Job Notifier](https://github.com/platanus/job_notifier) gem. 9 | - A way to customize the success and error partials. 10 | - A mechanism to listen job status changes and notify them using [jQuery Growl](http://ksylvest.github.io/jquery-growl/) 11 | 12 | ## Installation 13 | 14 | Add to your Gemfile: 15 | 16 | ```ruby 17 | source 'https://rails-assets.org' do 18 | gem 'rails-assets-growl', '~> 1.3.1' 19 | end 20 | 21 | gem "activeadmin_jobs" 22 | ``` 23 | 24 | ```bash 25 | bundle install 26 | ``` 27 | 28 | ```bash 29 | rails generate activeadmin_jobs:install 30 | ``` 31 | 32 | If you use `AdminUser` class in `ActiveAdmin` you will need to add the following code: 33 | 34 | ```ruby 35 | class AdminUser < ActiveRecord::Base 36 | include JobNotifier::Identifier 37 | identify_job_through(:id, :email) 38 | 39 | # more code... 40 | end 41 | 42 | ``` 43 | 44 | ## Usage 45 | 46 | To make it easy I'm going to explain how to use this gem with an example. 47 | 48 | Example: 49 | 50 | As an **admin user**: 51 | 52 | 1. From a form, I want to pick a big .xls file containing users information. 53 | 2. In the endpoint pointed by the form, I want to create a job to parse that heavy file in background to create users in the system. 54 | 3. I need a way to know when the process is completed. 55 | 4. Also, I want to see success and error feedback. 56 | 57 | 58 | 59 | Next, I will explain how to solve each step: 60 | 61 | #### Step 1: pick the file. 62 | 63 | Suppose you want to go to the import form from the `AdminUser`'s index page. To do that, you can add an `action_item` with a `collection_action`: 64 | 65 | */your_app/app/admin/admin_users.rb* 66 | 67 | ```ruby 68 | ActiveAdmin.register AdminUser do 69 | # more code... 70 | action_item :import_users, only: :index do 71 | link_to "Import Users", import_form_admin_admin_users_path 72 | end 73 | 74 | collection_action :import_form, title: "Import Users" do 75 | # Nothing here. We just want to render the form. 76 | end 77 | end 78 | ``` 79 | 80 | With the related wiew: 81 | 82 | *your_app/app/views/admin/admin_users/import_form.html.erb* 83 | 84 | ```erb 85 | <%= semantic_form_for :data, url: { action: :import }, method: :post do |f| %> 86 | <%= f.inputs "Form" do %> 87 | <%= f.input :source, as: :file, label: "File", :hint => "Excel file with thousands rows that need to be processed in background..." %> 88 | <% end %> 89 | <%= f.actions do %> 90 | <%= f.action :submit, as: :button, label: "Import" %> 91 | <% end %> 92 | <% end %> 93 | ``` 94 | 95 | 96 | 97 | You need to add the endpoint pointed in the form action too. 98 | 99 | */your_app/app/admin/admin_users.rb* 100 | 101 | ```ruby 102 | ActiveAdmin.register AdminUser do 103 | # more code... 104 | collection_action :import, title: "Import Users", method: :post do 105 | # We fill this in the next step. 106 | end 107 | end 108 | ``` 109 | 110 | #### Step 2: create a job. 111 | 112 | Inside the import action definition, you need to call the job in charge of parsing the .xls file. To do this: 113 | 114 | First, we need to create the job. We need to do it using `perform_with_feedback` method provided by [Job Notifier](https://github.com/platanus/job_notifier) gem. You can see how it works reading the **Third and Fourth Steps** of the [usage section](https://github.com/platanus/job_notifier#usage). 115 | 116 | */your_app/app/jobs/user_upload_job.rb* 117 | 118 | ```ruby 119 | class UserUploadJob < ActiveJob::Base 120 | def perform_with_feedback(xls_path) 121 | # Here you need to process the file an return a success or error result. 122 | # 123 | # Lets say I'm going to return this message: 124 | # 125 | # "Users successfully loaded" 126 | # 127 | # with a successful result and something like this: 128 | # 129 | # errors = [ 130 | # { row: 4, errors: ["Invalid First Name", "Invalid Category"] }, 131 | # { row: 6, errors: ["Invalid Last Name"] }, 132 | # { row: 84, errors: ["Invalid ID"] } 133 | # ] 134 | # 135 | # raise JobNotifier::Error::Validation.new(errors) 136 | # 137 | # with unsuccessful result. 138 | end 139 | end 140 | 141 | ``` 142 | 143 | Then, we call the job in the import action: 144 | 145 | */your_app/app/admin/admin_users.rb* 146 | 147 | ```ruby 148 | ActiveAdmin.register AdminUser do 149 | # more code... 150 | collection_action :import, title: "Import Users", method: :post do 151 | file_path = get_file_path(params[:data][:source]) # I'm not going to implement this. It's just an example. 152 | UserUploadJob.perform_later(current_admin_user.job_identifier, file_path) 153 | end 154 | end 155 | ``` 156 | 157 | #### Step 3: notify process completion. 158 | 159 | You don't need to do nothing here, the gem will do it for you using [jQuery Growl](http://ksylvest.github.io/jquery-growl/). 160 | 161 | On success... 162 | 163 | 164 | 165 | On error... 166 | 167 | 168 | 169 | #### Step 4: show success and error feedback. 170 | 171 | The gem includes an index view for jobs. There, you can see a jobs list with the current state of each job. 172 | 173 | 174 | 175 | To show feedback, you need to add one partial by possible job state prefixed by the job's class name in snake_case. For example: 176 | If you have the `UserUploadJob` job, following the convention: `_[job_class_name].[job_state].html.erb`, you will need two partials: 177 | 178 | One for success... 179 | 180 | */your_app/app/views/admin/jobs/_user_upload_job.finished.html.erb* 181 | 182 | ```erb 183 | <%= result %> 184 | ``` 185 | 186 | > Remember: we get this: "Users successfully loaded" as `result` on success. 187 | 188 | 189 | 190 | One for error... 191 | 192 | */your_app/app/views/admin/jobs/_user_upload_job.failed.html.erb* 193 | 194 | ```erb 195 |

Errors :(

196 | 197 | <% result.each do |record| %> 198 |

Row #<%= record[:row] %>:

199 | 204 | <% end %> 205 | ``` 206 | 207 | > Remember: we get something like this: 208 | ```ruby 209 | [ 210 | { row: 4, errors: ["Invalid First Name", "Invalid Category"] }, 211 | { row: 6, errors: ["Invalid Last Name"] }, 212 | { row: 84, errors: ["Invalid ID"] } 213 | ] 214 | ``` 215 | as `result` on error. 216 | 217 | 218 | 219 | Those partials will be rendered in the job's show view depending on its state. 220 | 221 | ## I18n 222 | 223 | If you want to translate your notifications, you can do it following this convention: 224 | 225 | **/your_app/config/locales/en.yml** 226 | 227 | ```yml 228 | en: 229 | activeadmin_jobs: 230 | [job_class_name]: 231 | description: "XXX" 232 | finished: 233 | title: "XXX" 234 | one: "XXX" 235 | other: "XXX" 236 | failed: 237 | title: "XXX" 238 | one: "XXX" 239 | other: "XXX" 240 | ``` 241 | 242 | For example: 243 | 244 | ```yml 245 | en: 246 | activeadmin_jobs: 247 | user_upload_job: 248 | description: "Users upload through .xls file" 249 | finished: 250 | title: "Users have been uploaded! :)" 251 | one: "One .xls file was completed with no errors. Click here to see the result" 252 | other: ".xls files were completed with no errors. Click here to see the result" 253 | failed: 254 | title: "Error trying to upload users :(" 255 | one: "One .xls file could not be uploaded. Click here to see errors" 256 | other: ".xls files could not be uploaded. Click here to see errors" 257 | ``` 258 | 259 | 260 | ## Contributing 261 | 262 | 1. Fork it 263 | 2. Create your feature branch (`git checkout -b my-new-feature`) 264 | 3. Commit your changes (`git commit -am 'Add some feature'`) 265 | 4. Push to the branch (`git push origin my-new-feature`) 266 | 5. Create new Pull Request 267 | 268 | ## Credits 269 | 270 | Thank you [contributors](https://github.com/platanus/activeadmin_jobs/graphs/contributors)! 271 | 272 | Platanus 273 | 274 | Active Admin Jobs is maintained by [platanus](http://platan.us). 275 | 276 | ## License 277 | 278 | Active Admin Jobs is © 2016 platanus, spa. It is free software and may be redistributed under the terms specified in the LICENSE file. 279 | -------------------------------------------------------------------------------- /spec/dummy/config/initializers/active_admin.rb: -------------------------------------------------------------------------------- 1 | ActiveAdmin.setup do |config| 2 | # == Site Title 3 | # 4 | # Set the title that is displayed on the main layout 5 | # for each of the active admin pages. 6 | # 7 | config.site_title = "Dummy" 8 | 9 | # Set the link url for the title. For example, to take 10 | # users to your main site. Defaults to no link. 11 | # 12 | # config.site_title_link = "/" 13 | 14 | # Set an optional image to be displayed for the header 15 | # instead of a string (overrides :site_title) 16 | # 17 | # Note: Aim for an image that's 21px high so it fits in the header. 18 | # 19 | # config.site_title_image = "logo.png" 20 | 21 | # == Default Namespace 22 | # 23 | # Set the default namespace each administration resource 24 | # will be added to. 25 | # 26 | # eg: 27 | # config.default_namespace = :hello_world 28 | # 29 | # This will create resources in the HelloWorld module and 30 | # will namespace routes to /hello_world/* 31 | # 32 | # To set no namespace by default, use: 33 | # config.default_namespace = false 34 | # 35 | # Default: 36 | # config.default_namespace = :admin 37 | # 38 | # You can customize the settings for each namespace by using 39 | # a namespace block. For example, to change the site title 40 | # within a namespace: 41 | # 42 | # config.namespace :admin do |admin| 43 | # admin.site_title = "Custom Admin Title" 44 | # end 45 | # 46 | # This will ONLY change the title for the admin section. Other 47 | # namespaces will continue to use the main "site_title" configuration. 48 | 49 | # == User Authentication 50 | # 51 | # Active Admin will automatically call an authentication 52 | # method in a before filter of all controller actions to 53 | # ensure that there is a currently logged in admin user. 54 | # 55 | # This setting changes the method which Active Admin calls 56 | # within the application controller. 57 | config.authentication_method = :authenticate_admin_user! 58 | 59 | # == User Authorization 60 | # 61 | # Active Admin will automatically call an authorization 62 | # method in a before filter of all controller actions to 63 | # ensure that there is a user with proper rights. You can use 64 | # CanCanAdapter or make your own. Please refer to documentation. 65 | # config.authorization_adapter = ActiveAdmin::CanCanAdapter 66 | 67 | # In case you prefer Pundit over other solutions you can here pass 68 | # the name of default policy class. This policy will be used in every 69 | # case when Pundit is unable to find suitable policy. 70 | # config.pundit_default_policy = "MyDefaultPunditPolicy" 71 | 72 | # You can customize your CanCan Ability class name here. 73 | # config.cancan_ability_class = "Ability" 74 | 75 | # You can specify a method to be called on unauthorized access. 76 | # This is necessary in order to prevent a redirect loop which happens 77 | # because, by default, user gets redirected to Dashboard. If user 78 | # doesn't have access to Dashboard, he'll end up in a redirect loop. 79 | # Method provided here should be defined in application_controller.rb. 80 | # config.on_unauthorized_access = :access_denied 81 | 82 | # == Current User 83 | # 84 | # Active Admin will associate actions with the current 85 | # user performing them. 86 | # 87 | # This setting changes the method which Active Admin calls 88 | # (within the application controller) to return the currently logged in user. 89 | config.current_user_method = :current_admin_user 90 | 91 | # == Logging Out 92 | # 93 | # Active Admin displays a logout link on each screen. These 94 | # settings configure the location and method used for the link. 95 | # 96 | # This setting changes the path where the link points to. If it's 97 | # a string, the strings is used as the path. If it's a Symbol, we 98 | # will call the method to return the path. 99 | # 100 | # Default: 101 | config.logout_link_path = :destroy_admin_user_session_path 102 | 103 | # This setting changes the http method used when rendering the 104 | # link. For example :get, :delete, :put, etc.. 105 | # 106 | # Default: 107 | # config.logout_link_method = :get 108 | 109 | # == Root 110 | # 111 | # Set the action to call for the root path. You can set different 112 | # roots for each namespace. 113 | # 114 | # Default: 115 | # config.root_to = 'dashboard#index' 116 | 117 | # == Admin Comments 118 | # 119 | # This allows your users to comment on any resource registered with Active Admin. 120 | # 121 | # You can completely disable comments: 122 | config.comments = false 123 | # 124 | # You can disable the menu item for the comments index page: 125 | # config.show_comments_in_menu = false 126 | # 127 | # You can change the name under which comments are registered: 128 | # config.comments_registration_name = 'AdminComment' 129 | # 130 | # You can change the order for the comments and you can change the column 131 | # to be used for ordering 132 | # config.comments_order = 'created_at ASC' 133 | 134 | # == Batch Actions 135 | # 136 | # Enable and disable Batch Actions 137 | # 138 | config.batch_actions = true 139 | 140 | # == Controller Filters 141 | # 142 | # You can add before, after and around filters to all of your 143 | # Active Admin resources and pages from here. 144 | # 145 | # config.before_filter :do_something_awesome 146 | 147 | # == Localize Date/Time Format 148 | # 149 | # Set the localize format to display dates and times. 150 | # To understand how to localize your app with I18n, read more at 151 | # https://github.com/svenfuchs/i18n/blob/master/lib%2Fi18n%2Fbackend%2Fbase.rb#L52 152 | # 153 | config.localize_format = :long 154 | 155 | # == Setting a Favicon 156 | # 157 | # config.favicon = 'favicon.ico' 158 | 159 | # == Meta Tags 160 | # 161 | # Add additional meta tags to the head element of active admin pages. 162 | # 163 | # Add tags to all pages logged in users see: 164 | # config.meta_tags = { author: 'My Company' } 165 | 166 | # By default, sign up/sign in/recover password pages are excluded 167 | # from showing up in search engine results by adding a robots meta 168 | # tag. You can reset the hash of meta tags included in logged out 169 | # pages: 170 | # config.meta_tags_for_logged_out_pages = {} 171 | 172 | # == Removing Breadcrumbs 173 | # 174 | # Breadcrumbs are enabled by default. You can customize them for individual 175 | # resources or you can disable them globally from here. 176 | # 177 | # config.breadcrumb = false 178 | 179 | # == Register Stylesheets & Javascripts 180 | # 181 | # We recommend using the built in Active Admin layout and loading 182 | # up your own stylesheets / javascripts to customize the look 183 | # and feel. 184 | # 185 | # To load a stylesheet: 186 | # config.register_stylesheet 'my_stylesheet.css' 187 | # 188 | # You can provide an options hash for more control, which is passed along to stylesheet_link_tag(): 189 | # config.register_stylesheet 'my_print_stylesheet.css', media: :print 190 | # 191 | # To load a javascript file: 192 | # config.register_javascript 'my_javascript.js' 193 | 194 | # == CSV options 195 | # 196 | # Set the CSV builder separator 197 | # config.csv_options = { col_sep: ';' } 198 | # 199 | # Force the use of quotes 200 | # config.csv_options = { force_quotes: true } 201 | 202 | # == Menu System 203 | # 204 | # You can add a navigation menu to be used in your application, or configure a provided menu 205 | # 206 | # To change the default utility navigation to show a link to your website & a logout btn 207 | # 208 | # config.namespace :admin do |admin| 209 | # admin.build_menu :utility_navigation do |menu| 210 | # menu.add label: "My Great Website", url: "http://www.mygreatwebsite.com", html_options: { target: :blank } 211 | # admin.add_logout_button_to_menu menu 212 | # end 213 | # end 214 | # 215 | # If you wanted to add a static menu item to the default menu provided: 216 | # 217 | # config.namespace :admin do |admin| 218 | # admin.build_menu :default do |menu| 219 | # menu.add label: "My Great Website", url: "http://www.mygreatwebsite.com", html_options: { target: :blank } 220 | # end 221 | # end 222 | 223 | # == Download Links 224 | # 225 | # You can disable download links on resource listing pages, 226 | # or customize the formats shown per namespace/globally 227 | # 228 | # To disable/customize for the :admin namespace: 229 | # 230 | # config.namespace :admin do |admin| 231 | # 232 | # # Disable the links entirely 233 | # admin.download_links = false 234 | # 235 | # # Only show XML & PDF options 236 | # admin.download_links = [:xml, :pdf] 237 | # 238 | # # Enable/disable the links based on block 239 | # # (for example, with cancan) 240 | # admin.download_links = proc { can?(:view_download_links) } 241 | # 242 | # end 243 | 244 | # == Pagination 245 | # 246 | # Pagination is enabled by default for all resources. 247 | # You can control the default per page count for all resources here. 248 | # 249 | # config.default_per_page = 30 250 | # 251 | # You can control the max per page count too. 252 | # 253 | # config.max_per_page = 10_000 254 | 255 | # == Filters 256 | # 257 | # By default the index screen includes a "Filters" sidebar on the right 258 | # hand side with a filter for each attribute of the registered model. 259 | # You can enable or disable them for all resources here. 260 | # 261 | # config.filters = true 262 | end 263 | -------------------------------------------------------------------------------- /spec/dummy/config/initializers/devise.rb: -------------------------------------------------------------------------------- 1 | # Use this hook to configure devise mailer, warden hooks and so forth. 2 | # Many of these configuration options can be set straight in your model. 3 | Devise.setup do |config| 4 | # The secret key used by Devise. Devise uses this key to generate 5 | # random tokens. Changing this key will render invalid all existing 6 | # confirmation, reset password and unlock tokens in the database. 7 | # Devise will use the `secret_key_base` on Rails 4+ applications as its `secret_key` 8 | # by default. You can change it below and use your own secret key. 9 | # config.secret_key = 'cc63f334aa166ce6d35d9548928178981723a353e77e2b49380acab95ade391e2a5ecf3596712660a91461e6861e3921d0f9ffe0861f85bdc0aecf54c7ba13b3' 10 | 11 | # ==> Mailer Configuration 12 | # Configure the e-mail address which will be shown in Devise::Mailer, 13 | # note that it will be overwritten if you use your own mailer class 14 | # with default "from" parameter. 15 | config.mailer_sender = 'please-change-me-at-config-initializers-devise@example.com' 16 | 17 | # Configure the class responsible to send e-mails. 18 | # config.mailer = 'Devise::Mailer' 19 | 20 | # ==> ORM configuration 21 | # Load and configure the ORM. Supports :active_record (default) and 22 | # :mongoid (bson_ext recommended) by default. Other ORMs may be 23 | # available as additional gems. 24 | require 'devise/orm/active_record' 25 | 26 | # ==> Configuration for any authentication mechanism 27 | # Configure which keys are used when authenticating a user. The default is 28 | # just :email. You can configure it to use [:username, :subdomain], so for 29 | # authenticating a user, both parameters are required. Remember that those 30 | # parameters are used only when authenticating and not when retrieving from 31 | # session. If you need permissions, you should implement that in a before filter. 32 | # You can also supply a hash where the value is a boolean determining whether 33 | # or not authentication should be aborted when the value is not present. 34 | # config.authentication_keys = [:email] 35 | 36 | # Configure parameters from the request object used for authentication. Each entry 37 | # given should be a request method and it will automatically be passed to the 38 | # find_for_authentication method and considered in your model lookup. For instance, 39 | # if you set :request_keys to [:subdomain], :subdomain will be used on authentication. 40 | # The same considerations mentioned for authentication_keys also apply to request_keys. 41 | # config.request_keys = [] 42 | 43 | # Configure which authentication keys should be case-insensitive. 44 | # These keys will be downcased upon creating or modifying a user and when used 45 | # to authenticate or find a user. Default is :email. 46 | config.case_insensitive_keys = [:email] 47 | 48 | # Configure which authentication keys should have whitespace stripped. 49 | # These keys will have whitespace before and after removed upon creating or 50 | # modifying a user and when used to authenticate or find a user. Default is :email. 51 | config.strip_whitespace_keys = [:email] 52 | 53 | # Tell if authentication through request.params is enabled. True by default. 54 | # It can be set to an array that will enable params authentication only for the 55 | # given strategies, for example, `config.params_authenticatable = [:database]` will 56 | # enable it only for database (email + password) authentication. 57 | # config.params_authenticatable = true 58 | 59 | # Tell if authentication through HTTP Auth is enabled. False by default. 60 | # It can be set to an array that will enable http authentication only for the 61 | # given strategies, for example, `config.http_authenticatable = [:database]` will 62 | # enable it only for database authentication. The supported strategies are: 63 | # :database = Support basic authentication with authentication key + password 64 | # config.http_authenticatable = false 65 | 66 | # If 401 status code should be returned for AJAX requests. True by default. 67 | # config.http_authenticatable_on_xhr = true 68 | 69 | # The realm used in Http Basic Authentication. 'Application' by default. 70 | # config.http_authentication_realm = 'Application' 71 | 72 | # It will change confirmation, password recovery and other workflows 73 | # to behave the same regardless if the e-mail provided was right or wrong. 74 | # Does not affect registerable. 75 | # config.paranoid = true 76 | 77 | # By default Devise will store the user in session. You can skip storage for 78 | # particular strategies by setting this option. 79 | # Notice that if you are skipping storage for all authentication paths, you 80 | # may want to disable generating routes to Devise's sessions controller by 81 | # passing skip: :sessions to `devise_for` in your config/routes.rb 82 | config.skip_session_storage = [:http_auth] 83 | 84 | # By default, Devise cleans up the CSRF token on authentication to 85 | # avoid CSRF token fixation attacks. This means that, when using AJAX 86 | # requests for sign in and sign up, you need to get a new CSRF token 87 | # from the server. You can disable this option at your own risk. 88 | # config.clean_up_csrf_token_on_authentication = true 89 | 90 | # ==> Configuration for :database_authenticatable 91 | # For bcrypt, this is the cost for hashing the password and defaults to 10. If 92 | # using other encryptors, it sets how many times you want the password re-encrypted. 93 | # 94 | # Limiting the stretches to just one in testing will increase the performance of 95 | # your test suite dramatically. However, it is STRONGLY RECOMMENDED to not use 96 | # a value less than 10 in other environments. Note that, for bcrypt (the default 97 | # encryptor), the cost increases exponentially with the number of stretches (e.g. 98 | # a value of 20 is already extremely slow: approx. 60 seconds for 1 calculation). 99 | config.stretches = Rails.env.test? ? 1 : 10 100 | 101 | # Setup a pepper to generate the encrypted password. 102 | # config.pepper = '955cf137850726892dec0f03226431a8eda8c1c969d7f22716509581371adece89bf35ee1aba222f9095df439eae3b4764e2856cf2d44b78ef1ee43772a64368' 103 | 104 | # Send a notification email when the user's password is changed 105 | # config.send_password_change_notification = false 106 | 107 | # ==> Configuration for :confirmable 108 | # A period that the user is allowed to access the website even without 109 | # confirming their account. For instance, if set to 2.days, the user will be 110 | # able to access the website for two days without confirming their account, 111 | # access will be blocked just in the third day. Default is 0.days, meaning 112 | # the user cannot access the website without confirming their account. 113 | # config.allow_unconfirmed_access_for = 2.days 114 | 115 | # A period that the user is allowed to confirm their account before their 116 | # token becomes invalid. For example, if set to 3.days, the user can confirm 117 | # their account within 3 days after the mail was sent, but on the fourth day 118 | # their account can't be confirmed with the token any more. 119 | # Default is nil, meaning there is no restriction on how long a user can take 120 | # before confirming their account. 121 | # config.confirm_within = 3.days 122 | 123 | # If true, requires any email changes to be confirmed (exactly the same way as 124 | # initial account confirmation) to be applied. Requires additional unconfirmed_email 125 | # db field (see migrations). Until confirmed, new email is stored in 126 | # unconfirmed_email column, and copied to email column on successful confirmation. 127 | config.reconfirmable = true 128 | 129 | # Defines which key will be used when confirming an account 130 | # config.confirmation_keys = [:email] 131 | 132 | # ==> Configuration for :rememberable 133 | # The time the user will be remembered without asking for credentials again. 134 | # config.remember_for = 2.weeks 135 | 136 | # Invalidates all the remember me tokens when the user signs out. 137 | config.expire_all_remember_me_on_sign_out = true 138 | 139 | # If true, extends the user's remember period when remembered via cookie. 140 | # config.extend_remember_period = false 141 | 142 | # Options to be passed to the created cookie. For instance, you can set 143 | # secure: true in order to force SSL only cookies. 144 | # config.rememberable_options = {} 145 | 146 | # ==> Configuration for :validatable 147 | # Range for password length. 148 | config.password_length = 8..72 149 | 150 | # Email regex used to validate email formats. It simply asserts that 151 | # one (and only one) @ exists in the given string. This is mainly 152 | # to give user feedback and not to assert the e-mail validity. 153 | # config.email_regexp = /\A[^@]+@[^@]+\z/ 154 | 155 | # ==> Configuration for :timeoutable 156 | # The time you want to timeout the user session without activity. After this 157 | # time the user will be asked for credentials again. Default is 30 minutes. 158 | # config.timeout_in = 30.minutes 159 | 160 | # ==> Configuration for :lockable 161 | # Defines which strategy will be used to lock an account. 162 | # :failed_attempts = Locks an account after a number of failed attempts to sign in. 163 | # :none = No lock strategy. You should handle locking by yourself. 164 | # config.lock_strategy = :failed_attempts 165 | 166 | # Defines which key will be used when locking and unlocking an account 167 | # config.unlock_keys = [:email] 168 | 169 | # Defines which strategy will be used to unlock an account. 170 | # :email = Sends an unlock link to the user email 171 | # :time = Re-enables login after a certain amount of time (see :unlock_in below) 172 | # :both = Enables both strategies 173 | # :none = No unlock strategy. You should handle unlocking by yourself. 174 | # config.unlock_strategy = :both 175 | 176 | # Number of authentication tries before locking an account if lock_strategy 177 | # is failed attempts. 178 | # config.maximum_attempts = 20 179 | 180 | # Time interval to unlock the account if :time is enabled as unlock_strategy. 181 | # config.unlock_in = 1.hour 182 | 183 | # Warn on the last attempt before the account is locked. 184 | # config.last_attempt_warning = true 185 | 186 | # ==> Configuration for :recoverable 187 | # 188 | # Defines which key will be used when recovering the password for an account 189 | # config.reset_password_keys = [:email] 190 | 191 | # Time interval you can reset your password with a reset password key. 192 | # Don't put a too small interval or your users won't have the time to 193 | # change their passwords. 194 | config.reset_password_within = 6.hours 195 | 196 | # When set to false, does not sign a user in automatically after their password is 197 | # reset. Defaults to true, so a user is signed in automatically after a reset. 198 | # config.sign_in_after_reset_password = true 199 | 200 | # ==> Configuration for :encryptable 201 | # Allow you to use another encryption algorithm besides bcrypt (default). You can use 202 | # :sha1, :sha512 or encryptors from others authentication tools as :clearance_sha1, 203 | # :authlogic_sha512 (then you should set stretches above to 20 for default behavior) 204 | # and :restful_authentication_sha1 (then you should set stretches to 10, and copy 205 | # REST_AUTH_SITE_KEY to pepper). 206 | # 207 | # Require the `devise-encryptable` gem when using anything other than bcrypt 208 | # config.encryptor = :sha512 209 | 210 | # ==> Scopes configuration 211 | # Turn scoped views on. Before rendering "sessions/new", it will first check for 212 | # "users/sessions/new". It's turned off by default because it's slower if you 213 | # are using only default views. 214 | # config.scoped_views = false 215 | 216 | # Configure the default scope given to Warden. By default it's the first 217 | # devise role declared in your routes (usually :user). 218 | # config.default_scope = :user 219 | 220 | # Set this configuration to false if you want /users/sign_out to sign out 221 | # only the current scope. By default, Devise signs out all scopes. 222 | # config.sign_out_all_scopes = true 223 | 224 | # ==> Navigation configuration 225 | # Lists the formats that should be treated as navigational. Formats like 226 | # :html, should redirect to the sign in page when the user does not have 227 | # access, but formats like :xml or :json, should return 401. 228 | # 229 | # If you have any extra navigational formats, like :iphone or :mobile, you 230 | # should add them to the navigational formats lists. 231 | # 232 | # The "*/*" below is required to match Internet Explorer requests. 233 | # config.navigational_formats = ['*/*', :html] 234 | 235 | # The default HTTP method used to sign out a resource. Default is :delete. 236 | config.sign_out_via = :delete 237 | 238 | # ==> OmniAuth 239 | # Add a new OmniAuth provider. Check the wiki for more information on setting 240 | # up on your models and hooks. 241 | # config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo' 242 | 243 | # ==> Warden configuration 244 | # If you want to use other strategies, that are not supported by Devise, or 245 | # change the failure app, you can configure them inside the config.warden block. 246 | # 247 | # config.warden do |manager| 248 | # manager.intercept_401 = false 249 | # manager.default_strategies(scope: :user).unshift :some_external_strategy 250 | # end 251 | 252 | # ==> Mountable engine configurations 253 | # When using Devise inside an engine, let's call it `MyEngine`, and this engine 254 | # is mountable, there are some extra configurations to be taken into account. 255 | # The following options are available, assuming the engine is mounted as: 256 | # 257 | # mount MyEngine, at: '/my_engine' 258 | # 259 | # The router that invoked `devise_for`, in the example above, would be: 260 | # config.router_name = :my_engine 261 | # 262 | # When using OmniAuth, Devise cannot automatically set OmniAuth path, 263 | # so you need to do it manually. For the users scope, it would be: 264 | # config.omniauth_path_prefix = '/my_engine/users/auth' 265 | end 266 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | AllCops: 2 | Include: 3 | - "**/*.rake" 4 | - "**/Gemfile" 5 | - "**/Rakefile" 6 | Exclude: 7 | - "vendor/**/*" 8 | - "db/**/*" 9 | - "bin/**/*" 10 | DisplayCopNames: false 11 | StyleGuideCopsOnly: false 12 | TargetRubyVersion: 2.3 13 | Layout/AccessModifierIndentation: 14 | Description: Check indentation of private/protected visibility modifiers. 15 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#indent-public-private-protected 16 | Enabled: true 17 | EnforcedStyle: indent 18 | SupportedStyles: 19 | - outdent 20 | - indent 21 | Layout/AlignHash: 22 | Description: Align the elements of a hash literal if they span more than one line. 23 | Enabled: true 24 | EnforcedHashRocketStyle: key 25 | EnforcedColonStyle: key 26 | EnforcedLastArgumentHashStyle: always_inspect 27 | SupportedLastArgumentHashStyles: 28 | - always_inspect 29 | - always_ignore 30 | - ignore_implicit 31 | - ignore_explicit 32 | Layout/AlignParameters: 33 | Description: Align the parameters of a method call if they span more than one line. 34 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-double-indent 35 | Enabled: true 36 | EnforcedStyle: with_fixed_indentation 37 | SupportedStyles: 38 | - with_first_parameter 39 | - with_fixed_indentation 40 | Style/AndOr: 41 | Description: Use &&/|| instead of and/or. 42 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-and-or-or 43 | Enabled: true 44 | EnforcedStyle: always 45 | SupportedStyles: 46 | - always 47 | - conditionals 48 | Style/BarePercentLiterals: 49 | Description: Checks if usage of %() or %Q() matches configuration. 50 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#percent-q-shorthand 51 | Enabled: true 52 | EnforcedStyle: bare_percent 53 | SupportedStyles: 54 | - percent_q 55 | - bare_percent 56 | Metrics/BlockLength: 57 | Enabled: false 58 | Style/BracesAroundHashParameters: 59 | Description: Enforce braces style around hash parameters. 60 | Enabled: true 61 | EnforcedStyle: no_braces 62 | SupportedStyles: 63 | - braces 64 | - no_braces 65 | - context_dependent 66 | Layout/CaseIndentation: 67 | Description: Indentation of when in a case/when/[else/]end. 68 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#indent-when-to-case 69 | Enabled: true 70 | EnforcedStyle: case 71 | SupportedStyles: 72 | - case 73 | - end 74 | IndentOneStep: false 75 | Style/ClassAndModuleChildren: 76 | Description: Checks style of children classes and modules. 77 | Enabled: false 78 | EnforcedStyle: nested 79 | SupportedStyles: 80 | - nested 81 | - compact 82 | Style/ClassCheck: 83 | Description: Enforces consistent use of `Object#is_a?` or `Object#kind_of?`. 84 | Enabled: true 85 | EnforcedStyle: is_a? 86 | SupportedStyles: 87 | - is_a? 88 | - kind_of? 89 | Style/CollectionMethods: 90 | Description: Preferred collection methods. 91 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#map-find-select-reduce-size 92 | Enabled: false 93 | PreferredMethods: 94 | collect: map 95 | collect!: map! 96 | inject: reduce 97 | detect: find 98 | find_all: select 99 | find: detect 100 | Style/CommentAnnotation: 101 | Description: Checks formatting of special comments (TODO, FIXME, OPTIMIZE, HACK, 102 | REVIEW). 103 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#annotate-keywords 104 | Enabled: false 105 | Keywords: 106 | - TODO 107 | - FIXME 108 | - OPTIMIZE 109 | - HACK 110 | - REVIEW 111 | Layout/DotPosition: 112 | Description: Checks the position of the dot in multi-line method calls. 113 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#consistent-multi-line-chains 114 | Enabled: true 115 | EnforcedStyle: leading 116 | SupportedStyles: 117 | - leading 118 | - trailing 119 | Layout/EmptyLineBetweenDefs: 120 | Description: Use empty lines between defs. 121 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#empty-lines-between-methods 122 | Enabled: true 123 | AllowAdjacentOneLineDefs: false 124 | Layout/EmptyLinesAroundBlockBody: 125 | Description: Keeps track of empty lines around block bodies. 126 | Enabled: true 127 | EnforcedStyle: no_empty_lines 128 | SupportedStyles: 129 | - empty_lines 130 | - no_empty_lines 131 | Layout/EmptyLinesAroundClassBody: 132 | Description: Keeps track of empty lines around class bodies. 133 | Enabled: true 134 | EnforcedStyle: no_empty_lines 135 | SupportedStyles: 136 | - empty_lines 137 | - no_empty_lines 138 | Layout/EmptyLinesAroundModuleBody: 139 | Description: Keeps track of empty lines around module bodies. 140 | Enabled: true 141 | EnforcedStyle: no_empty_lines 142 | SupportedStyles: 143 | - empty_lines 144 | - no_empty_lines 145 | Style/Encoding: 146 | Description: Use UTF-8 as the source file encoding. 147 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#utf-8 148 | Enabled: false 149 | EnforcedStyle: always 150 | SupportedStyles: 151 | - when_needed 152 | - always 153 | Style/FileName: 154 | Description: Use snake_case for source file names. 155 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#snake-case-files 156 | Enabled: false 157 | Exclude: [] 158 | Layout/FirstParameterIndentation: 159 | Description: Checks the indentation of the first parameter in a method call. 160 | Enabled: true 161 | EnforcedStyle: special_for_inner_method_call_in_parentheses 162 | SupportedStyles: 163 | - consistent 164 | - special_for_inner_method_call 165 | - special_for_inner_method_call_in_parentheses 166 | Style/For: 167 | Description: Checks use of for or each in multiline loops. 168 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-for-loops 169 | Enabled: true 170 | EnforcedStyle: each 171 | SupportedStyles: 172 | - for 173 | - each 174 | Style/FormatString: 175 | Description: Enforce the use of Kernel#sprintf, Kernel#format or String#%. 176 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#sprintf 177 | Enabled: false 178 | EnforcedStyle: format 179 | SupportedStyles: 180 | - format 181 | - sprintf 182 | - percent 183 | Style/FrozenStringLiteralComment: 184 | Enabled: false 185 | Style/GlobalVars: 186 | Description: Do not introduce global variables. 187 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#instance-vars 188 | Enabled: false 189 | AllowedVariables: [] 190 | Style/GuardClause: 191 | Description: Check for conditionals that can be replaced with guard clauses 192 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-nested-conditionals 193 | Enabled: false 194 | MinBodyLength: 1 195 | Style/HashSyntax: 196 | Description: 'Prefer Ruby 1.9 hash syntax { a: 1, b: 2 } over 1.8 syntax { :a => 197 | 1, :b => 2 }.' 198 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#hash-literals 199 | Enabled: true 200 | EnforcedStyle: ruby19 201 | SupportedStyles: 202 | - ruby19 203 | - hash_rockets 204 | Style/IfUnlessModifier: 205 | Description: Favor modifier if/unless usage when you have a single-line body. 206 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#if-as-a-modifier 207 | Enabled: false 208 | MaxLineLength: 80 209 | Layout/IndentationWidth: 210 | Description: Use 2 spaces for indentation. 211 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#spaces-indentation 212 | Enabled: true 213 | Width: 2 214 | Layout/IndentHash: 215 | Description: Checks the indentation of the first key in a hash literal. 216 | Enabled: true 217 | EnforcedStyle: special_inside_parentheses 218 | SupportedStyles: 219 | - special_inside_parentheses 220 | - consistent 221 | Style/LambdaCall: 222 | Description: Use lambda.call(...) instead of lambda.(...). 223 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#proc-call 224 | Enabled: false 225 | EnforcedStyle: call 226 | SupportedStyles: 227 | - call 228 | - braces 229 | Style/Next: 230 | Description: Use `next` to skip iteration instead of a condition at the end. 231 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-nested-conditionals 232 | Enabled: false 233 | EnforcedStyle: skip_modifier_ifs 234 | MinBodyLength: 3 235 | SupportedStyles: 236 | - skip_modifier_ifs 237 | - always 238 | Style/NonNilCheck: 239 | Description: Checks for redundant nil checks. 240 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-non-nil-checks 241 | Enabled: true 242 | IncludeSemanticChanges: false 243 | Style/MethodDefParentheses: 244 | Description: Checks if the method definitions have or don't have parentheses. 245 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#method-parens 246 | Enabled: true 247 | EnforcedStyle: require_parentheses 248 | SupportedStyles: 249 | - require_parentheses 250 | - require_no_parentheses 251 | Style/MethodName: 252 | Description: Use the configured style when naming methods. 253 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#snake-case-symbols-methods-vars 254 | Enabled: true 255 | EnforcedStyle: snake_case 256 | SupportedStyles: 257 | - snake_case 258 | - camelCase 259 | Layout/MultilineOperationIndentation: 260 | Description: Checks indentation of binary operations that span more than one line. 261 | Enabled: true 262 | EnforcedStyle: indented 263 | SupportedStyles: 264 | - aligned 265 | - indented 266 | Style/MutableConstant: 267 | Description: Do not assign mutable objects to constants. 268 | Enabled: false 269 | Style/NumericLiterals: 270 | Description: Add underscores to large numeric literals to improve their readability. 271 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#underscores-in-numerics 272 | Enabled: false 273 | MinDigits: 5 274 | Style/ParenthesesAroundCondition: 275 | Description: Don't use parentheses around the condition of an if/unless/while. 276 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-parens-if 277 | Enabled: true 278 | AllowSafeAssignment: true 279 | Style/PercentLiteralDelimiters: 280 | Description: Use `%`-literal delimiters consistently 281 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#percent-literal-braces 282 | Enabled: false 283 | PreferredDelimiters: 284 | "%": "()" 285 | "%i": "()" 286 | "%q": "()" 287 | "%Q": "()" 288 | "%r": "{}" 289 | "%s": "()" 290 | "%w": "()" 291 | "%W": "()" 292 | "%x": "()" 293 | Style/PercentQLiterals: 294 | Description: Checks if uses of %Q/%q match the configured preference. 295 | Enabled: true 296 | EnforcedStyle: lower_case_q 297 | SupportedStyles: 298 | - lower_case_q 299 | - upper_case_q 300 | Style/PredicateName: 301 | Description: Check the names of predicate methods. 302 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#bool-methods-qmark 303 | Enabled: true 304 | NamePrefix: 305 | - is_ 306 | - has_ 307 | - have_ 308 | NamePrefixBlacklist: 309 | - is_ 310 | Style/RaiseArgs: 311 | Description: Checks the arguments passed to raise/fail. 312 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#exception-class-messages 313 | Enabled: false 314 | EnforcedStyle: exploded 315 | SupportedStyles: 316 | - compact 317 | - exploded 318 | Style/RedundantReturn: 319 | Description: Don't use return where it's not required. 320 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-explicit-return 321 | Enabled: true 322 | AllowMultipleReturnValues: false 323 | Style/Semicolon: 324 | Description: Don't use semicolons to terminate expressions. 325 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-semicolon 326 | Enabled: true 327 | AllowAsExpressionSeparator: false 328 | Style/SignalException: 329 | Description: Checks for proper usage of fail and raise. 330 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#fail-method 331 | Enabled: false 332 | EnforcedStyle: semantic 333 | SupportedStyles: 334 | - only_raise 335 | - only_fail 336 | - semantic 337 | Style/SingleLineBlockParams: 338 | Description: Enforces the names of some block params. 339 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#reduce-blocks 340 | Enabled: false 341 | Methods: 342 | - reduce: 343 | - a 344 | - e 345 | - inject: 346 | - a 347 | - e 348 | Style/SingleLineMethods: 349 | Description: Avoid single-line methods. 350 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-single-line-methods 351 | Enabled: false 352 | AllowIfMethodIsEmpty: true 353 | Style/StringLiterals: 354 | Description: Checks if uses of quotes match the configured preference. 355 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#consistent-string-literals 356 | Enabled: false 357 | EnforcedStyle: double_quotes 358 | SupportedStyles: 359 | - single_quotes 360 | - double_quotes 361 | Style/StringLiteralsInInterpolation: 362 | Description: Checks if uses of quotes inside expressions in interpolated strings 363 | match the configured preference. 364 | Enabled: true 365 | EnforcedStyle: single_quotes 366 | SupportedStyles: 367 | - single_quotes 368 | - double_quotes 369 | Layout/SpaceAroundBlockParameters: 370 | Description: Checks the spacing inside and after block parameters pipes. 371 | Enabled: true 372 | EnforcedStyleInsidePipes: no_space 373 | SupportedStylesInsidePipes: 374 | - space 375 | - no_space 376 | Layout/SpaceAroundEqualsInParameterDefault: 377 | Description: Checks that the equals signs in parameter default assignments have 378 | or don't have surrounding space depending on configuration. 379 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#spaces-around-equals 380 | Enabled: true 381 | EnforcedStyle: space 382 | SupportedStyles: 383 | - space 384 | - no_space 385 | Layout/SpaceBeforeBlockBraces: 386 | Description: Checks that the left block brace has or doesn't have space before it. 387 | Enabled: true 388 | EnforcedStyle: space 389 | SupportedStyles: 390 | - space 391 | - no_space 392 | Layout/SpaceInsideBlockBraces: 393 | Description: Checks that block braces have or don't have surrounding space. For 394 | blocks taking parameters, checks that the left brace has or doesn't have trailing 395 | space. 396 | Enabled: true 397 | EnforcedStyle: space 398 | SupportedStyles: 399 | - space 400 | - no_space 401 | EnforcedStyleForEmptyBraces: no_space 402 | SpaceBeforeBlockParameters: true 403 | Layout/SpaceInsideHashLiteralBraces: 404 | Description: Use spaces inside hash literal braces - or don't. 405 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#spaces-operators 406 | Enabled: true 407 | EnforcedStyle: space 408 | EnforcedStyleForEmptyBraces: no_space 409 | SupportedStyles: 410 | - space 411 | - no_space 412 | Style/SymbolProc: 413 | Description: Use symbols as procs instead of blocks when possible. 414 | Enabled: true 415 | IgnoredMethods: 416 | - respond_to 417 | Layout/TrailingBlankLines: 418 | Description: Checks trailing blank lines and final newline. 419 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#newline-eof 420 | Enabled: true 421 | EnforcedStyle: final_newline 422 | SupportedStyles: 423 | - final_newline 424 | - final_blank_line 425 | Style/TrailingCommaInArguments: 426 | Description: Checks for trailing comma in argument lists. 427 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-trailing-array-commas 428 | Enabled: true 429 | Style/TrailingCommaInLiteral: 430 | Description: Checks for trailing comma in array and hash literals. 431 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-trailing-array-commas 432 | Enabled: true 433 | Style/TrivialAccessors: 434 | Description: Prefer attr_* methods to trivial readers/writers. 435 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#attr_family 436 | Enabled: false 437 | ExactNameMatch: false 438 | AllowPredicates: false 439 | AllowDSLWriters: false 440 | Whitelist: 441 | - to_ary 442 | - to_a 443 | - to_c 444 | - to_enum 445 | - to_h 446 | - to_hash 447 | - to_i 448 | - to_int 449 | - to_io 450 | - to_open 451 | - to_path 452 | - to_proc 453 | - to_r 454 | - to_regexp 455 | - to_str 456 | - to_s 457 | - to_sym 458 | Style/VariableName: 459 | Description: Use the configured style when naming variables. 460 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#snake-case-symbols-methods-vars 461 | Enabled: true 462 | EnforcedStyle: snake_case 463 | SupportedStyles: 464 | - snake_case 465 | - camelCase 466 | Style/WhileUntilModifier: 467 | Description: Favor modifier while/until usage when you have a single-line body. 468 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#while-as-a-modifier 469 | Enabled: false 470 | MaxLineLength: 80 471 | Style/WordArray: 472 | Description: Use %w or %W for arrays of words. 473 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#percent-w 474 | Enabled: false 475 | MinSize: 0 476 | WordRegex: !ruby/regexp /\A[\p{Word}]+\z/ 477 | Metrics/AbcSize: 478 | Description: A calculated magnitude based on number of assignments, branches, and 479 | conditions. 480 | Enabled: true 481 | Max: 25 482 | Metrics/BlockNesting: 483 | Description: Avoid excessive block nesting 484 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#three-is-the-number-thou-shalt-count 485 | Enabled: true 486 | Max: 3 487 | Metrics/ClassLength: 488 | Description: Avoid classes longer than 100 lines of code. 489 | Enabled: false 490 | CountComments: false 491 | Max: 100 492 | Metrics/CyclomaticComplexity: 493 | Description: A complexity metric that is strongly correlated to the number of test 494 | cases needed to validate a method. 495 | Enabled: true 496 | Max: 6 497 | Metrics/LineLength: 498 | Description: Limit lines to 100 characters. 499 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#100-character-limits 500 | Enabled: true 501 | Max: 100 502 | AllowURI: true 503 | URISchemes: 504 | - http 505 | - https 506 | Metrics/MethodLength: 507 | Description: Avoid methods longer than 15 lines of code. 508 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#short-methods 509 | Enabled: true 510 | CountComments: true 511 | Max: 15 512 | Exclude: 513 | - "spec/**/*" 514 | Metrics/ParameterLists: 515 | Description: Avoid long parameter lists. 516 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#too-many-params 517 | Enabled: false 518 | Max: 5 519 | CountKeywordArgs: true 520 | Metrics/PerceivedComplexity: 521 | Description: A complexity metric geared towards measuring complexity for a human 522 | reader. 523 | Enabled: true 524 | Max: 7 525 | Lint/AssignmentInCondition: 526 | Description: Don't use assignment in conditions. 527 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#safe-assignment-in-condition 528 | Enabled: false 529 | AllowSafeAssignment: true 530 | Lint/EndAlignment: 531 | Description: Align ends correctly. 532 | Enabled: true 533 | EnforcedStyleAlignWith: keyword 534 | SupportedStylesAlignWith: 535 | - keyword 536 | - variable 537 | Lint/DefEndAlignment: 538 | Description: Align ends corresponding to defs correctly. 539 | Enabled: true 540 | EnforcedStyleAlignWith: start_of_line 541 | SupportedStylesAlignWith: 542 | - start_of_line 543 | - def 544 | Rails/ActionFilter: 545 | Description: Enforces consistent use of action filter methods. 546 | Enabled: true 547 | EnforcedStyle: action 548 | SupportedStyles: 549 | - action 550 | - filter 551 | Include: 552 | - app/controllers/**/*.rb 553 | Rails/HasAndBelongsToMany: 554 | Description: Prefer has_many :through to has_and_belongs_to_many. 555 | Enabled: true 556 | Include: 557 | - app/models/**/*.rb 558 | Rails/Output: 559 | Description: Checks for calls to puts, print, etc. 560 | Enabled: true 561 | Include: 562 | - app/**/*.rb 563 | - config/**/*.rb 564 | - db/**/*.rb 565 | - lib/**/*.rb 566 | Rails/ReadWriteAttribute: 567 | Description: Checks for read_attribute(:attr) and write_attribute(:attr, val). 568 | Enabled: true 569 | Include: 570 | - app/models/**/*.rb 571 | Rails/ScopeArgs: 572 | Description: Checks the arguments of ActiveRecord scopes. 573 | Enabled: true 574 | Include: 575 | - app/models/**/*.rb 576 | Rails/Validation: 577 | Description: Use validates :attribute, hash of validations. 578 | Enabled: true 579 | Include: 580 | - app/models/**/*.rb 581 | Style/InlineComment: 582 | Description: Avoid inline comments. 583 | Enabled: false 584 | Style/MethodCalledOnDoEndBlock: 585 | Description: Avoid chaining a method call on a do...end block. 586 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#single-line-blocks 587 | Enabled: false 588 | Style/SymbolArray: 589 | Description: Use %i or %I for arrays of symbols. 590 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#percent-i 591 | Enabled: false 592 | Layout/ExtraSpacing: 593 | Description: Do not use unnecessary spacing. 594 | Enabled: false 595 | Style/AccessorMethodName: 596 | Description: Check the naming of accessor methods for get_/set_. 597 | Enabled: false 598 | Style/Alias: 599 | Description: Use alias_method instead of alias. 600 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#alias-method 601 | Enabled: false 602 | Layout/AlignArray: 603 | Description: Align the elements of an array literal if they span more than one line. 604 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#align-multiline-arrays 605 | Enabled: true 606 | Style/ArrayJoin: 607 | Description: Use Array#join instead of Array#*. 608 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#array-join 609 | Enabled: false 610 | Style/AsciiComments: 611 | Description: Use only ascii symbols in comments. 612 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#english-comments 613 | Enabled: false 614 | Style/AsciiIdentifiers: 615 | Description: Use only ascii symbols in identifiers. 616 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#english-identifiers 617 | Enabled: false 618 | Style/Attr: 619 | Description: Checks for uses of Module#attr. 620 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#attr 621 | Enabled: false 622 | Style/BeginBlock: 623 | Description: Avoid the use of BEGIN blocks. 624 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-BEGIN-blocks 625 | Enabled: true 626 | Style/BlockComments: 627 | Description: Do not use block comments. 628 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-block-comments 629 | Enabled: false 630 | Layout/BlockEndNewline: 631 | Description: Put end statement of multiline block on its own line. 632 | Enabled: true 633 | Style/CaseEquality: 634 | Description: Avoid explicit use of the case equality operator(===). 635 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-case-equality 636 | Enabled: false 637 | Style/CharacterLiteral: 638 | Description: Checks for uses of character literals. 639 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-character-literals 640 | Enabled: false 641 | Style/ClassAndModuleCamelCase: 642 | Description: Use CamelCase for classes and modules. 643 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#camelcase-classes 644 | Enabled: true 645 | Style/ClassMethods: 646 | Description: Use self when defining module/class methods. 647 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#def-self-singletons 648 | Enabled: true 649 | Style/ClassVars: 650 | Description: Avoid the use of class variables. 651 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-class-vars 652 | Enabled: false 653 | Style/ColonMethodCall: 654 | Description: 'Do not use :: for method call.' 655 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#double-colons 656 | Enabled: false 657 | Layout/CommentIndentation: 658 | Description: Indentation of comments. 659 | Enabled: true 660 | Style/ConstantName: 661 | Description: Constants should use SCREAMING_SNAKE_CASE. 662 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#screaming-snake-case 663 | Enabled: true 664 | Style/DefWithParentheses: 665 | Description: Use def with parentheses when there are arguments. 666 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#method-parens 667 | Enabled: true 668 | Style/PreferredHashMethods: 669 | Description: Checks for use of deprecated Hash methods. 670 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#hash-key 671 | Enabled: false 672 | Style/Documentation: 673 | Description: Document classes and non-namespace modules. 674 | Enabled: false 675 | Style/DoubleNegation: 676 | Description: Checks for uses of double negation (!!). 677 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-bang-bang 678 | Enabled: false 679 | Style/EachWithObject: 680 | Description: Prefer `each_with_object` over `inject` or `reduce`. 681 | Enabled: false 682 | Layout/ElseAlignment: 683 | Description: Align elses and elsifs correctly. 684 | Enabled: true 685 | Style/EmptyElse: 686 | Description: Avoid empty else-clauses. 687 | Enabled: true 688 | Layout/EmptyLines: 689 | Description: Don't use several empty lines in a row. 690 | Enabled: true 691 | Layout/EmptyLinesAroundAccessModifier: 692 | Description: Keep blank lines around access modifiers. 693 | Enabled: true 694 | Layout/EmptyLinesAroundMethodBody: 695 | Description: Keeps track of empty lines around method bodies. 696 | Enabled: true 697 | Style/EmptyLiteral: 698 | Description: Prefer literals to Array.new/Hash.new/String.new. 699 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#literal-array-hash 700 | Enabled: false 701 | Style/EndBlock: 702 | Description: Avoid the use of END blocks. 703 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-END-blocks 704 | Enabled: true 705 | Layout/EndOfLine: 706 | Description: Use Unix-style line endings. 707 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#crlf 708 | Enabled: true 709 | Style/EvenOdd: 710 | Description: Favor the use of Fixnum#even? && Fixnum#odd? 711 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#predicate-methods 712 | Enabled: false 713 | Style/FlipFlop: 714 | Description: Checks for flip flops 715 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-flip-flops 716 | Enabled: false 717 | Style/IfWithSemicolon: 718 | Description: Do not use if x; .... Use the ternary operator instead. 719 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-semicolon-ifs 720 | Enabled: false 721 | Layout/IndentationConsistency: 722 | Description: Keep indentation straight. 723 | Enabled: true 724 | Layout/IndentArray: 725 | Description: Checks the indentation of the first element in an array literal. 726 | Enabled: true 727 | Style/InfiniteLoop: 728 | Description: Use Kernel#loop for infinite loops. 729 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#infinite-loop 730 | Enabled: true 731 | Style/Lambda: 732 | Description: Use the new lambda literal syntax for single-line blocks. 733 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#lambda-multi-line 734 | Enabled: false 735 | Layout/LeadingCommentSpace: 736 | Description: Comments should start with a space. 737 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#hash-space 738 | Enabled: true 739 | Style/LineEndConcatenation: 740 | Description: Use \ instead of + or << to concatenate two string literals at line 741 | end. 742 | Enabled: false 743 | Style/MethodCallWithoutArgsParentheses: 744 | Description: Do not use parentheses for method calls with no arguments. 745 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-args-no-parens 746 | Enabled: true 747 | Style/ModuleFunction: 748 | Description: Checks for usage of `extend self` in modules. 749 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#module-function 750 | Enabled: false 751 | Style/MultilineBlockChain: 752 | Description: Avoid multi-line chains of blocks. 753 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#single-line-blocks 754 | Enabled: false 755 | Layout/MultilineBlockLayout: 756 | Description: Ensures newlines after multiline block do statements. 757 | Enabled: false 758 | Style/MultilineIfThen: 759 | Description: Do not use then for multi-line if/unless. 760 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-then 761 | Enabled: true 762 | Style/MultilineTernaryOperator: 763 | Description: 'Avoid multi-line ?: (the ternary operator); use if/unless instead.' 764 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-multiline-ternary 765 | Enabled: true 766 | Style/NegatedIf: 767 | Description: Favor unless over if for negative conditions (or control flow or). 768 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#unless-for-negatives 769 | Enabled: false 770 | Style/NegatedWhile: 771 | Description: Favor until over while for negative conditions. 772 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#until-for-negatives 773 | Enabled: false 774 | Style/NestedTernaryOperator: 775 | Description: Use one expression per branch in a ternary operator. 776 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-nested-ternary 777 | Enabled: true 778 | Style/NilComparison: 779 | Description: Prefer x.nil? to x == nil. 780 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#predicate-methods 781 | Enabled: false 782 | Style/Not: 783 | Description: Use ! instead of not. 784 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#bang-not-not 785 | Enabled: true 786 | Style/OneLineConditional: 787 | Description: Favor the ternary operator(?:) over if/then/else/end constructs. 788 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#ternary-operator 789 | Enabled: false 790 | Style/OpMethod: 791 | Description: When defining binary operators, name the argument other. 792 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#other-arg 793 | Enabled: false 794 | Style/PerlBackrefs: 795 | Description: Avoid Perl-style regex back references. 796 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-perl-regexp-last-matchers 797 | Enabled: false 798 | Style/Proc: 799 | Description: Use proc instead of Proc.new. 800 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#proc 801 | Enabled: false 802 | Style/RedundantBegin: 803 | Description: Don't use begin blocks when they are not needed. 804 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#begin-implicit 805 | Enabled: true 806 | Style/RedundantException: 807 | Description: Checks for an obsolete RuntimeException argument in raise/fail. 808 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-explicit-runtimeerror 809 | Enabled: true 810 | Style/RedundantSelf: 811 | Description: Don't use self where it's not needed. 812 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-self-unless-required 813 | Enabled: true 814 | Style/RescueModifier: 815 | Description: Avoid using rescue in its modifier form. 816 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-rescue-modifiers 817 | Enabled: true 818 | Style/SelfAssignment: 819 | Description: Checks for places where self-assignment shorthand should have been 820 | used. 821 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#self-assignment 822 | Enabled: false 823 | Layout/SpaceAfterColon: 824 | Description: Use spaces after colons. 825 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#spaces-operators 826 | Enabled: true 827 | Layout/SpaceAfterComma: 828 | Description: Use spaces after commas. 829 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#spaces-operators 830 | Enabled: true 831 | Layout/SpaceAroundKeyword: 832 | Description: Use a space around keywords if appropriate. 833 | Enabled: true 834 | Layout/SpaceAfterMethodName: 835 | Description: Do not put a space between a method name and the opening parenthesis 836 | in a method definition. 837 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#parens-no-spaces 838 | Enabled: true 839 | Layout/SpaceAfterNot: 840 | Description: Tracks redundant space after the ! operator. 841 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-space-bang 842 | Enabled: true 843 | Layout/SpaceAfterSemicolon: 844 | Description: Use spaces after semicolons. 845 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#spaces-operators 846 | Enabled: true 847 | Layout/SpaceBeforeComma: 848 | Description: No spaces before commas. 849 | Enabled: true 850 | Layout/SpaceBeforeComment: 851 | Description: Checks for missing space between code and a comment on the same line. 852 | Enabled: true 853 | Layout/SpaceBeforeFirstArg: 854 | Description: Put a space between a method name and the first argument in a method 855 | call without parentheses. 856 | Enabled: true 857 | Layout/SpaceBeforeSemicolon: 858 | Description: No spaces before semicolons. 859 | Enabled: true 860 | Layout/SpaceAroundOperators: 861 | Description: Use spaces around operators. 862 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#spaces-operators 863 | Enabled: true 864 | Layout/SpaceInsideBrackets: 865 | Description: No spaces after [ or before ]. 866 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-spaces-braces 867 | Enabled: true 868 | Layout/SpaceInsideParens: 869 | Description: No spaces after ( or before ). 870 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-spaces-braces 871 | Enabled: true 872 | Layout/SpaceInsideRangeLiteral: 873 | Description: No spaces inside range literals. 874 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-space-inside-range-literals 875 | Enabled: true 876 | Style/SpecialGlobalVars: 877 | Description: Avoid Perl-style global variables. 878 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-cryptic-perlisms 879 | Enabled: false 880 | Style/StructInheritance: 881 | Description: Checks for inheritance from Struct.new. 882 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-extend-struct-new 883 | Enabled: true 884 | Layout/Tab: 885 | Description: No hard tabs. 886 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#spaces-indentation 887 | Enabled: true 888 | Layout/TrailingWhitespace: 889 | Description: Avoid trailing whitespace. 890 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-trailing-whitespace 891 | Enabled: true 892 | Style/UnlessElse: 893 | Description: Do not use unless with else. Rewrite these with the positive case first. 894 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-else-with-unless 895 | Enabled: true 896 | Style/UnneededCapitalW: 897 | Description: Checks for %W when interpolation is not needed. 898 | Enabled: true 899 | Style/UnneededPercentQ: 900 | Description: Checks for %q/%Q when single quotes or double quotes would do. 901 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#percent-q 902 | Enabled: true 903 | Style/VariableInterpolation: 904 | Description: Don't interpolate global, instance and class variables directly in 905 | strings. 906 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#curlies-interpolate 907 | Enabled: false 908 | Style/WhenThen: 909 | Description: Use when x then ... for one-line cases. 910 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#one-line-cases 911 | Enabled: false 912 | Style/WhileUntilDo: 913 | Description: Checks for redundant do after while or until. 914 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-multiline-while-do 915 | Enabled: true 916 | Lint/AmbiguousOperator: 917 | Description: Checks for ambiguous operators in the first argument of a method invocation 918 | without parentheses. 919 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#parens-as-args 920 | Enabled: false 921 | Lint/AmbiguousRegexpLiteral: 922 | Description: Checks for ambiguous regexp literals in the first argument of a method 923 | invocation without parenthesis. 924 | Enabled: false 925 | Lint/BlockAlignment: 926 | Description: Align block ends correctly. 927 | Enabled: true 928 | Lint/ConditionPosition: 929 | Description: Checks for condition placed in a confusing position relative to the 930 | keyword. 931 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#same-line-condition 932 | Enabled: false 933 | Lint/Debugger: 934 | Description: Check for debugger calls. 935 | Enabled: true 936 | Lint/DeprecatedClassMethods: 937 | Description: Check for deprecated class method calls. 938 | Enabled: false 939 | Lint/DuplicateMethods: 940 | Description: Check for duplicate methods calls. 941 | Enabled: true 942 | Lint/ElseLayout: 943 | Description: Check for odd code arrangement in an else block. 944 | Enabled: false 945 | Lint/EmptyEnsure: 946 | Description: Checks for empty ensure block. 947 | Enabled: true 948 | Lint/EmptyInterpolation: 949 | Description: Checks for empty string interpolation. 950 | Enabled: true 951 | Lint/EndInMethod: 952 | Description: END blocks should not be placed inside method definitions. 953 | Enabled: true 954 | Lint/EnsureReturn: 955 | Description: Do not use return in an ensure block. 956 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-return-ensure 957 | Enabled: true 958 | Security/Eval: 959 | Description: The use of eval represents a serious security risk. 960 | Enabled: true 961 | Lint/HandleExceptions: 962 | Description: Don't suppress exception. 963 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#dont-hide-exceptions 964 | Enabled: false 965 | Lint/InvalidCharacterLiteral: 966 | Description: Checks for invalid character literals with a non-escaped whitespace 967 | character. 968 | Enabled: false 969 | Lint/LiteralInCondition: 970 | Description: Checks of literals used in conditions. 971 | Enabled: false 972 | Lint/LiteralInInterpolation: 973 | Description: Checks for literals used in interpolation. 974 | Enabled: false 975 | Lint/Loop: 976 | Description: Use Kernel#loop with break rather than begin/end/until or begin/end/while 977 | for post-loop tests. 978 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#loop-with-break 979 | Enabled: false 980 | Lint/ParenthesesAsGroupedExpression: 981 | Description: Checks for method calls with a space before the opening parenthesis. 982 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#parens-no-spaces 983 | Enabled: false 984 | Lint/RequireParentheses: 985 | Description: Use parentheses in the method call to avoid confusion about precedence. 986 | Enabled: false 987 | Lint/RescueException: 988 | Description: Avoid rescuing the Exception class. 989 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-blind-rescues 990 | Enabled: true 991 | Lint/ShadowingOuterLocalVariable: 992 | Description: Do not use the same name as outer local variable for block arguments 993 | or block local variables. 994 | Enabled: true 995 | Lint/StringConversionInInterpolation: 996 | Description: Checks for Object#to_s usage in string interpolation. 997 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#no-to-s 998 | Enabled: true 999 | Lint/UnderscorePrefixedVariableName: 1000 | Description: Do not use prefix `_` for a variable that is used. 1001 | Enabled: false 1002 | Lint/UnusedBlockArgument: 1003 | Description: Checks for unused block arguments. 1004 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#underscore-unused-vars 1005 | Enabled: true 1006 | Lint/UnusedMethodArgument: 1007 | Description: Checks for unused method arguments. 1008 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#underscore-unused-vars 1009 | Enabled: true 1010 | Lint/UnreachableCode: 1011 | Description: Unreachable code. 1012 | Enabled: true 1013 | Lint/UselessAccessModifier: 1014 | Description: Checks for useless access modifiers. 1015 | Enabled: true 1016 | Lint/UselessAssignment: 1017 | Description: Checks for useless assignment to a local variable. 1018 | StyleGuide: https://github.com/bbatsov/ruby-style-guide#underscore-unused-vars 1019 | Enabled: true 1020 | Lint/UselessComparison: 1021 | Description: Checks for comparison of something with itself. 1022 | Enabled: true 1023 | Lint/UselessElseWithoutRescue: 1024 | Description: Checks for useless `else` in `begin..end` without `rescue`. 1025 | Enabled: true 1026 | Lint/UselessSetterCall: 1027 | Description: Checks for useless setter call to a local variable. 1028 | Enabled: true 1029 | Lint/Void: 1030 | Description: Possible use of operator/literal/variable in void context. 1031 | Enabled: false 1032 | Rails/Delegate: 1033 | Description: Prefer delegate method for delegations. 1034 | Enabled: false 1035 | Performance/RedundantBlockCall: 1036 | Description: Use `yield` instead of `block.call`. 1037 | Reference: https://github.com/JuanitoFatas/fast-ruby#proccall-vs-yield-code 1038 | Enabled: false 1039 | --------------------------------------------------------------------------------