├── spec
├── dummy
│ ├── log
│ │ └── .gitkeep
│ ├── app
│ │ ├── mailers
│ │ │ └── .gitkeep
│ │ ├── models
│ │ │ ├── .gitkeep
│ │ │ ├── category.rb
│ │ │ ├── ability.rb
│ │ │ ├── admin_user.rb
│ │ │ └── post.rb
│ │ ├── assets
│ │ │ ├── images
│ │ │ │ └── .keep
│ │ │ ├── javascripts
│ │ │ │ ├── active_admin.js
│ │ │ │ └── application.js
│ │ │ ├── config
│ │ │ │ └── manifest.js
│ │ │ └── stylesheets
│ │ │ │ ├── application.css
│ │ │ │ └── active_admin.css.scss
│ │ ├── helpers
│ │ │ └── application_helper.rb
│ │ ├── controllers
│ │ │ └── application_controller.rb
│ │ ├── views
│ │ │ └── layouts
│ │ │ │ └── application.html.erb
│ │ └── admin
│ │ │ ├── categories.rb
│ │ │ ├── posts.rb
│ │ │ ├── admin_users.rb
│ │ │ └── dashboard.rb
│ ├── lib
│ │ └── assets
│ │ │ └── .gitkeep
│ ├── public
│ │ ├── favicon.ico
│ │ ├── 500.html
│ │ ├── 422.html
│ │ └── 404.html
│ ├── config
│ │ ├── database.travis.yml
│ │ ├── environment.rb
│ │ ├── initializers
│ │ │ ├── mime_types.rb
│ │ │ ├── backtrace_silencers.rb
│ │ │ ├── session_store.rb
│ │ │ ├── secret_token.rb
│ │ │ ├── wrap_parameters.rb
│ │ │ ├── inflections.rb
│ │ │ ├── active_admin.rb
│ │ │ └── devise.rb
│ │ ├── boot.rb
│ │ ├── locales
│ │ │ ├── en.yml
│ │ │ └── devise.en.yml
│ │ ├── database.sample.yml
│ │ ├── environments
│ │ │ ├── development.rb
│ │ │ ├── test.rb
│ │ │ └── production.rb
│ │ ├── routes.rb
│ │ └── application.rb
│ ├── config.ru
│ ├── db
│ │ ├── seeds.rb
│ │ ├── migrate
│ │ │ ├── 20131025231118_add_super_admin_to_admin_users.rb
│ │ │ ├── 20130829000200_create_categories.rb
│ │ │ ├── 20190606153623_sqlite3_represent_boolean_as_integer.rb
│ │ │ ├── 20130817005638_create_posts.rb
│ │ │ ├── 20130817004306_create_admin_notes.rb
│ │ │ ├── 20130817004307_move_admin_notes_to_comments.rb
│ │ │ └── 20130817004304_devise_create_admin_users.rb
│ │ └── schema.rb
│ ├── Rakefile
│ ├── bin
│ │ └── rails
│ ├── script
│ │ └── rails
│ └── README.rdoc
├── support
│ ├── .gitkeep
│ └── post_helpers.rb
├── factories
│ ├── admin_users.rb
│ ├── categories.rb
│ └── posts.rb
├── features
│ ├── authorization_spec.rb
│ ├── custom_block_spec.rb
│ └── js_confirmation_spec.rb
└── spec_helper.rb
├── .rspec
├── lib
└── active_admin
│ ├── workflow
│ ├── version.rb
│ └── dsl.rb
│ └── workflow.rb
├── .gitignore
├── Rakefile
├── .travis.yml
├── Gemfile
├── MIT-LICENSE
├── active_admin-workflow.gemspec
└── README.md
/spec/dummy/log/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/spec/support/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/spec/dummy/app/mailers/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/spec/dummy/app/models/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/spec/dummy/lib/assets/.gitkeep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/spec/dummy/public/favicon.ico:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/spec/dummy/app/assets/images/.keep:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/.rspec:
--------------------------------------------------------------------------------
1 | --color
2 | --format progress
3 |
--------------------------------------------------------------------------------
/spec/dummy/app/assets/javascripts/active_admin.js:
--------------------------------------------------------------------------------
1 | //= require active_admin/base
2 |
--------------------------------------------------------------------------------
/spec/dummy/app/helpers/application_helper.rb:
--------------------------------------------------------------------------------
1 | module ApplicationHelper
2 | end
3 |
--------------------------------------------------------------------------------
/spec/dummy/app/models/category.rb:
--------------------------------------------------------------------------------
1 | class Category < ActiveRecord::Base
2 | has_many :posts
3 | end
4 |
--------------------------------------------------------------------------------
/lib/active_admin/workflow/version.rb:
--------------------------------------------------------------------------------
1 | module ActiveAdmin
2 | module Workflow
3 | VERSION = "0.1.0"
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/spec/dummy/config/database.travis.yml:
--------------------------------------------------------------------------------
1 | test:
2 | adapter: postgresql
3 | database: aa_workflow_test
4 | username: postgres
5 |
--------------------------------------------------------------------------------
/spec/dummy/app/controllers/application_controller.rb:
--------------------------------------------------------------------------------
1 | class ApplicationController < ActionController::Base
2 | protect_from_forgery
3 | end
4 |
--------------------------------------------------------------------------------
/spec/dummy/app/assets/config/manifest.js:
--------------------------------------------------------------------------------
1 | //= link_tree ../images
2 | //= link_directory ../javascripts .js
3 | //= link_directory ../stylesheets .css
4 |
--------------------------------------------------------------------------------
/lib/active_admin/workflow.rb:
--------------------------------------------------------------------------------
1 | require 'active_admin'
2 | require 'workflow'
3 |
4 | require 'active_admin/workflow/dsl'
5 |
6 | ActiveAdmin::DSL.send :include, ActiveAdmin::Workflow::DSL
7 |
--------------------------------------------------------------------------------
/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 Dummy::Application
5 |
--------------------------------------------------------------------------------
/spec/dummy/db/seeds.rb:
--------------------------------------------------------------------------------
1 | AdminUser.create!(:email => 'admin@example.com', :password => 'password', :password_confirmation => 'password') unless AdminUser.exists?(email: 'admin@example.com')
2 |
--------------------------------------------------------------------------------
/spec/dummy/config/environment.rb:
--------------------------------------------------------------------------------
1 | # Load the rails application
2 | require File.expand_path('../application', __FILE__)
3 |
4 | # Initialize the rails application
5 | Dummy::Application.initialize!
6 |
--------------------------------------------------------------------------------
/spec/dummy/db/migrate/20131025231118_add_super_admin_to_admin_users.rb:
--------------------------------------------------------------------------------
1 | class AddSuperAdminToAdminUsers < ActiveRecord::Migration
2 | def change
3 | add_column :admin_users, :super_admin, :boolean, default: false
4 | end
5 | end
6 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .bundle/
2 | log/*.log
3 | pkg/
4 | spec/dummy/config/database.yml
5 | spec/dummy/db/*.sqlite3
6 | spec/dummy/log/*.log
7 | spec/dummy/tmp/
8 | spec/dummy/.sass-cache
9 | Gemfile.lock
10 | .DS_Store
11 | *.gem
12 | .ruby-version
13 |
--------------------------------------------------------------------------------
/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 | # Mime::Type.register_alias "text/html", :iphone
6 |
--------------------------------------------------------------------------------
/spec/factories/admin_users.rb:
--------------------------------------------------------------------------------
1 | FactoryBot.define do
2 | factory :user, class: "AdminUser" do
3 | sequence(:email) { |n| "user#{n}@example.com" }
4 | password { "Password1" }
5 | password_confirmation { "Password1" }
6 | super_admin { false }
7 | end
8 | end
9 |
--------------------------------------------------------------------------------
/spec/dummy/config/boot.rb:
--------------------------------------------------------------------------------
1 | require 'rubygems'
2 | gemfile = File.expand_path('../../../../Gemfile', __FILE__)
3 |
4 | if File.exist?(gemfile)
5 | ENV['BUNDLE_GEMFILE'] = gemfile
6 | require 'bundler'
7 | Bundler.setup
8 | end
9 |
10 | $:.unshift File.expand_path('../../../../lib', __FILE__)
--------------------------------------------------------------------------------
/spec/dummy/Rakefile:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env rake
2 | # Add your own tasks in files placed in lib/tasks ending in .rake,
3 | # for example lib/tasks/capistrano.rake, and they will automatically be available to Rake.
4 |
5 | require File.expand_path('../config/application', __FILE__)
6 |
7 | Dummy::Application.load_tasks
8 |
--------------------------------------------------------------------------------
/spec/dummy/db/migrate/20130829000200_create_categories.rb:
--------------------------------------------------------------------------------
1 | class CreateCategories < ActiveRecord::Migration
2 | def change
3 | create_table :categories do |t|
4 | t.string :name
5 |
6 | t.timestamps
7 | end
8 |
9 | add_column :posts, :category_id, :integer
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/spec/dummy/bin/rails:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | begin
3 | load File.expand_path('../spring', __FILE__)
4 | rescue LoadError => e
5 | raise unless e.message.include?('spring')
6 | end
7 | APP_PATH = File.expand_path('../config/application', __dir__)
8 | require_relative '../config/boot'
9 | require 'rails/commands'
10 |
--------------------------------------------------------------------------------
/spec/dummy/db/migrate/20190606153623_sqlite3_represent_boolean_as_integer.rb:
--------------------------------------------------------------------------------
1 | class Sqlite3RepresentBooleanAsInteger < ActiveRecord::Migration[5.2]
2 | def change
3 | AdminUser.where("super_admin = 't'").update_all(super_admin: 1)
4 | AdminUser.where("super_admin = 'f'").update_all(super_admin: 0)
5 | end
6 | end
7 |
--------------------------------------------------------------------------------
/spec/dummy/app/models/ability.rb:
--------------------------------------------------------------------------------
1 | class Ability
2 | include CanCan::Ability
3 |
4 | def initialize(user)
5 | if user.super_admin?
6 | can :manage, :all
7 | else
8 | can :read, ActiveAdmin::Page, name: "Dashboard"
9 | can [:read, :show, :index], [Category, Post]
10 | end
11 | end
12 | end
13 |
--------------------------------------------------------------------------------
/spec/dummy/script/rails:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env ruby
2 | # This command will automatically be run when you run "rails" with Rails 3 gems installed from the root of your application.
3 |
4 | APP_PATH = File.expand_path('../../config/application', __FILE__)
5 | require File.expand_path('../../config/boot', __FILE__)
6 | require 'rails/commands'
7 |
--------------------------------------------------------------------------------
/spec/dummy/db/migrate/20130817005638_create_posts.rb:
--------------------------------------------------------------------------------
1 | class CreatePosts < ActiveRecord::Migration
2 | def change
3 | create_table :posts do |t|
4 | t.string :title, null: false
5 | t.text :body, null: false
6 | t.string :workflow_state, null: false
7 |
8 | t.timestamps
9 | end
10 | end
11 | end
12 |
--------------------------------------------------------------------------------
/spec/dummy/app/models/admin_user.rb:
--------------------------------------------------------------------------------
1 | class AdminUser < ActiveRecord::Base
2 | # Include default devise modules. Others available are:
3 | # :token_authenticatable, :confirmable,
4 | # :lockable, :timeoutable and :omniauthable
5 | devise :database_authenticatable,
6 | :recoverable, :rememberable, :trackable, :validatable
7 | end
8 |
--------------------------------------------------------------------------------
/spec/dummy/app/views/layouts/application.html.erb:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | Dummy
5 | <%= stylesheet_link_tag "application", :media => "all" %>
6 | <%= javascript_include_tag "application" %>
7 | <%= csrf_meta_tags %>
8 |
9 |
10 |
11 | <%= yield %>
12 |
13 |
14 |
15 |
--------------------------------------------------------------------------------
/spec/dummy/config/locales/en.yml:
--------------------------------------------------------------------------------
1 | # Sample localization file for English. Add more files in this directory for other locales.
2 | # See https://github.com/svenfuchs/rails-i18n/tree/master/rails%2Flocale for starting points.
3 |
4 | en:
5 | posts:
6 | publish:
7 | label: Publish Post
8 | confirm: Do you want to publish now?
9 | flash:
10 | success: Post successfully published
11 |
--------------------------------------------------------------------------------
/spec/factories/categories.rb:
--------------------------------------------------------------------------------
1 | FactoryBot.define do
2 | factory :category do
3 | sequence(:name) { |n| "Category #{n}" }
4 |
5 | transient do
6 | num_posts { 0 }
7 | end
8 |
9 | after(:create) do |category, evaluator|
10 | if evaluator.num_posts > 0
11 | evaluator.num_posts.times do
12 | create(:post, category: category)
13 | end
14 | end
15 | end
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/spec/dummy/app/admin/categories.rb:
--------------------------------------------------------------------------------
1 | ActiveAdmin.register Category do
2 | action_item_args = if ActiveAdmin::VERSION.start_with?('0.')
3 | [{ only: :show }]
4 | else
5 | ["state_action_category", { only: :show }]
6 | end
7 | action_item(*action_item_args) do
8 | link_to "Posts", admin_category_posts_path(resource)
9 | end
10 | end
11 |
--------------------------------------------------------------------------------
/spec/factories/posts.rb:
--------------------------------------------------------------------------------
1 | FactoryBot.define do
2 | factory :post do
3 | sequence(:title) { |n| "Post #{n}" }
4 | body { "lorem ipsum" }
5 | category
6 |
7 | trait :reviewed do
8 | workflow_state { Post::REVIEWED }
9 | end
10 |
11 | trait :published do
12 | workflow_state { Post::PUBLISHED }
13 | end
14 |
15 | trait :archived do
16 | workflow_state { Post::ARCHIVED }
17 | end
18 | end
19 | end
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 |
--------------------------------------------------------------------------------
/spec/dummy/config/initializers/session_store.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | Dummy::Application.config.session_store :cookie_store, key: '_dummy_session'
4 |
5 | # Use the database for sessions instead of the cookie-based default,
6 | # which shouldn't be used to store highly confidential information
7 | # (create the session table with "rails generate session_migration")
8 | # Dummy::Application.config.session_store :active_record_store
9 |
--------------------------------------------------------------------------------
/Rakefile:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env rake
2 | begin
3 | require 'bundler/setup'
4 | rescue LoadError
5 | puts 'You must `gem install bundler` and `bundle install` to run rake tasks'
6 | end
7 |
8 | APP_RAKEFILE = File.expand_path("../spec/dummy/Rakefile", __FILE__)
9 | Bundler::GemHelper.install_tasks
10 |
11 | require 'rspec/core'
12 | require 'rspec/core/rake_task'
13 |
14 | desc "Run all specs in spec directory (excluding plugin specs)"
15 | RSpec::Core::RakeTask.new(:spec => 'app:db:test:prepare')
16 |
17 | task :default => :spec
18 |
--------------------------------------------------------------------------------
/spec/dummy/config/initializers/secret_token.rb:
--------------------------------------------------------------------------------
1 | # Be sure to restart your server when you modify this file.
2 |
3 | # Your secret key for verifying the integrity of signed cookies.
4 | # If you change this key, all old signed cookies will become invalid!
5 | # Make sure the secret is at least 30 characters and all random,
6 | # no regular words or you'll be exposed to dictionary attacks.
7 | Dummy::Application.config.secret_key_base = 'b4d434f4302cbecdfddd1412aeb90a60bd825668d5d204aa6b948ef76adedd2465a7ccac67a7d0251b6a78beb56520207337a12736dd971dcc0c91251a24cd95'
8 |
--------------------------------------------------------------------------------
/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]
9 | end
10 |
11 | # Disable root element in JSON by default.
12 | ActiveSupport.on_load(:active_record) do
13 | self.include_root_in_json = false
14 | end
15 |
--------------------------------------------------------------------------------
/spec/dummy/app/admin/posts.rb:
--------------------------------------------------------------------------------
1 | ActiveAdmin.register Post do
2 | belongs_to :category
3 |
4 | state_action :peer_review
5 | state_action :publish, confirm: true # Has I18n in locale
6 | state_action :archive, confirm: ->{ "Do you want to archive?" }
7 |
8 | # No I18n for confirm message
9 | state_action :reopen, confirm: true, http_verb: :get do
10 | redirect_to admin_dashboard_path
11 | end
12 |
13 | form do |f|
14 | f.inputs "Post Details" do
15 | f.input :title
16 | f.input :body
17 | end
18 | f.actions
19 | end
20 |
21 | end
22 |
--------------------------------------------------------------------------------
/spec/dummy/db/migrate/20130817004306_create_admin_notes.rb:
--------------------------------------------------------------------------------
1 | class CreateAdminNotes < ActiveRecord::Migration
2 | def self.up
3 | create_table :admin_notes do |t|
4 | t.string :resource_id, :null => false
5 | t.string :resource_type, :null => false
6 | t.references :admin_user, :polymorphic => true
7 | t.text :body
8 | t.timestamps
9 | end
10 | add_index :admin_notes, [:resource_type, :resource_id]
11 | add_index :admin_notes, [:admin_user_type, :admin_user_id]
12 | end
13 |
14 | def self.down
15 | drop_table :admin_notes
16 | end
17 | end
18 |
--------------------------------------------------------------------------------
/spec/support/post_helpers.rb:
--------------------------------------------------------------------------------
1 | def post_expect_have_workflow_state(workflow_state)
2 | within ".attributes_table" do
3 | expect(page).to have_content(workflow_state, normalize_ws: true)
4 | end
5 | end
6 |
7 | def login_and_navigate_to_post(user, post)
8 | login_as user
9 | visit admin_category_post_path(post.category, post)
10 | end
11 |
12 | def has_action_item(item)
13 | within ".action_items" do
14 | expect(page).to have_link(item)
15 | end
16 | end
17 |
18 | def has_no_action_item(item)
19 | within ".action_items" do
20 | expect(page).not_to have_link(item)
21 | end
22 | end
23 |
--------------------------------------------------------------------------------
/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
4 | # (all these examples are active by default):
5 | # ActiveSupport::Inflector.inflections do |inflect|
6 | # inflect.plural /^(ox)$/i, '\1en'
7 | # inflect.singular /^(ox)en/i, '\1'
8 | # inflect.irregular 'person', 'people'
9 | # inflect.uncountable %w( fish sheep )
10 | # end
11 | #
12 | # These inflection rules are supported but not enabled by default:
13 | # ActiveSupport::Inflector.inflections do |inflect|
14 | # inflect.acronym 'RESTful'
15 | # end
16 |
--------------------------------------------------------------------------------
/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 vendor/assets/stylesheets of plugins, if any, 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 top of the
9 | * compiled file, but it's generally better to create a new file per style scope.
10 | *
11 | *= require_self
12 | *= require_tree .
13 | */
14 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | script: xvfb-run bundle exec rspec spec
2 | rvm:
3 | - 2.6.3
4 | addons:
5 | chrome: stable
6 | services:
7 | - postgresql
8 | before_install:
9 | - gem update --system
10 | - gem --version
11 | - gem install bundler
12 | before_script:
13 | - psql -c 'create database aa_workflow_test;' -U postgres
14 | - cp spec/dummy/config/database.travis.yml spec/dummy/config/database.yml
15 | - RAILS_ENV=test cd spec/dummy && bundle exec rake db:setup
16 | - cd ../../
17 | env:
18 | - RAILS_VERSION=6.0.0
19 | - RAILS_VERSION=5.2.3
20 | - RAILS_VERSION=5.1.7
21 | - RAILS_VERSION=5.0.7.2
22 | - RAILS_VERSION=4.2.11.1
23 |
--------------------------------------------------------------------------------
/spec/features/authorization_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | feature "Authorized Access" do
4 |
5 | given(:user) { create(:user) }
6 | given(:admin) { create(:user, super_admin: true) }
7 |
8 | given(:category) { create(:category, num_posts: 1) }
9 | given(:post) { category.posts.first }
10 |
11 | scenario 'should not show button if not authorized' do
12 | login_and_navigate_to_post user, post
13 |
14 | has_no_action_item "Peer Review"
15 | end
16 |
17 | scenario 'should show button if authorized' do
18 | login_and_navigate_to_post admin, post
19 |
20 | has_action_item "Peer Review"
21 | end
22 |
23 | end
24 |
--------------------------------------------------------------------------------
/spec/dummy/config/database.sample.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 | development:
7 | adapter: sqlite3
8 | database: db/development.sqlite3
9 | pool: 5
10 | timeout: 5000
11 |
12 | # Warning: The database defined as "test" will be erased and
13 | # re-generated from your development database when you run "rake".
14 | # Do not set this db to the same as development or production.
15 | test:
16 | adapter: sqlite3
17 | database: db/test.sqlite3
18 | pool: 5
19 | timeout: 5000
20 |
21 | production:
22 | adapter: sqlite3
23 | database: db/production.sqlite3
24 | pool: 5
25 | timeout: 5000
26 |
--------------------------------------------------------------------------------
/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 vendor/assets/javascripts of plugins, if any, 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 | // the compiled file.
9 | //
10 | // WARNING: THE FIRST BLANK LINE MARKS THE END OF WHAT'S TO BE PROCESSED, ANY BLANK LINE SHOULD
11 | // GO AFTER THE REQUIRES BELOW.
12 | //
13 | //= require jquery
14 | //= require jquery_ujs
15 | //= require_tree .
16 |
--------------------------------------------------------------------------------
/spec/dummy/app/models/post.rb:
--------------------------------------------------------------------------------
1 | class Post < ActiveRecord::Base
2 | include WorkflowActiverecord
3 |
4 | belongs_to :category
5 |
6 | validates :title, presence: true, uniqueness: true
7 | validates :body, presence: true
8 |
9 | DRAFT = 'draft'
10 | REVIEWED = 'reviewed'
11 | PUBLISHED = 'published'
12 | ARCHIVED = 'archived'
13 |
14 | workflow do
15 | state DRAFT do
16 | event :peer_review, transitions_to: REVIEWED
17 | end
18 | state REVIEWED do
19 | event :publish, transitions_to: PUBLISHED
20 | end
21 | state PUBLISHED do
22 | event :archive, transitions_to: ARCHIVED
23 | end
24 | state ARCHIVED do
25 | event :reopen, transitions_to: DRAFT
26 | end
27 | end
28 | end
29 |
--------------------------------------------------------------------------------
/spec/features/custom_block_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | feature "Custom Block" do
4 |
5 | given(:admin) { create(:user, super_admin: true) }
6 |
7 | given(:category) { create(:category, num_posts: 0) }
8 | given(:post) { create(:post, :archived, category: category) }
9 |
10 | scenario 'uses block for controller action if provided' do
11 | login_and_navigate_to_post admin, post
12 |
13 | click_link "Reopen"
14 |
15 | expect(current_path).to eq(admin_dashboard_path)
16 | expect(be_reviewed)
17 | end
18 |
19 | scenario 'respects :http_verb provided' do
20 | login_and_navigate_to_post admin, post
21 |
22 | link = find(".action_item a", text: "Reopen")
23 | expect(link['data-method']).to eq('get')
24 | end
25 | end
26 |
--------------------------------------------------------------------------------
/spec/dummy/public/500.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | We're sorry, but something went wrong (500)
5 |
17 |
18 |
19 |
20 |
21 |
22 |
We're sorry, but something went wrong.
23 |
24 |
25 |
26 |
--------------------------------------------------------------------------------
/spec/dummy/app/admin/admin_users.rb:
--------------------------------------------------------------------------------
1 | ActiveAdmin.register AdminUser do
2 | index do
3 | column :email
4 | column :current_sign_in_at
5 | column :last_sign_in_at
6 | column :sign_in_count
7 | default_actions
8 | end
9 |
10 | filter :email
11 |
12 | form do |f|
13 | f.inputs "Admin Details" do
14 | f.input :email
15 | f.input :password
16 | f.input :password_confirmation
17 | end
18 | f.actions
19 | end
20 | end
21 |
--------------------------------------------------------------------------------
/spec/dummy/public/422.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | The change you wanted was rejected (422)
5 |
17 |
18 |
19 |
20 |
21 |
22 |
The change you wanted was rejected.
23 |
Maybe you tried to change something you didn't have access to.
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/spec/dummy/public/404.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | The page you were looking for doesn't exist (404)
5 |
17 |
18 |
19 |
20 |
21 |
22 |
The page you were looking for doesn't exist.
23 |
You may have mistyped the address or the page may have moved.
24 |
25 |
26 |
27 |
--------------------------------------------------------------------------------
/Gemfile:
--------------------------------------------------------------------------------
1 | source "https://rubygems.org"
2 |
3 | # Declare your gem's dependencies in active_admin-workflow.gemspec.
4 | # Bundler will treat runtime dependencies like base dependencies, and
5 | # development dependencies will be added by default to the :development group.
6 | gemspec
7 |
8 | # Declare any dependencies that are still in development here instead of in
9 | # your gemspec. These might include edge Rails or gems from your path or
10 | # Git. Remember to move these dependencies to your gemspec before releasing
11 | # your gem to rubygems.org.
12 |
13 | # To use debugger
14 | # gem 'debugger'
15 |
16 | group :assets do
17 | gem 'sass-rails'
18 | gem 'coffee-rails'
19 | gem 'uglifier'
20 | gem 'jquery-rails'
21 | end
22 |
23 | group :development, :test do
24 | gem 'pry'
25 | end
26 |
27 | gem 'rails'
28 | gem "sqlite3", '~> 1.3.6'
29 | gem 'cancan'
30 | gem 'activeadmin'
31 | gem 'workflow-activerecord', '>= 4.1', '< 6.0'
32 |
--------------------------------------------------------------------------------
/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 |
--------------------------------------------------------------------------------
/MIT-LICENSE:
--------------------------------------------------------------------------------
1 | Copyright 2013 YOURNAME
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/assets/stylesheets/active_admin.css.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 |
14 | // Overriding any non-variable SASS must be done after the fact.
15 | // For example, to change the default status-tag color:
16 | //
17 | // body.active_admin {
18 | // .status_tag { background: #6090DB; }
19 | // }
20 | //
21 | // Notice that Active Admin CSS rules are nested within a
22 | // 'body.active_admin' selector to prevent conflicts with
23 | // other pages in the app. It is best to wrap your changes in a
24 | // namespace so they are properly recognized. You have options
25 | // if you e.g. want different styles for different namespaces:
26 | //
27 | // .active_admin applies to any Active Admin namespace
28 | // .admin_namespace applies to the admin namespace (eg: /admin)
29 | // .other_namespace applies to a custom namespace named other (eg: /other)
30 |
--------------------------------------------------------------------------------
/spec/dummy/config/environments/development.rb:
--------------------------------------------------------------------------------
1 | require 'pry'
2 | Dummy::Application.configure do
3 | # Settings specified here will take precedence over those in config/application.rb
4 |
5 | # In the development environment your application's code is reloaded on
6 | # every request. This slows down response time but is perfect for development
7 | # since you don't have to restart the web server when you make code changes.
8 | config.cache_classes = false
9 |
10 | # Do not eager load code on boot.
11 | config.eager_load = false
12 |
13 | # Log error messages when you accidentally call methods on nil.
14 | config.whiny_nils = true
15 |
16 | # Show full error reports and disable caching
17 | config.consider_all_requests_local = true
18 | config.action_controller.perform_caching = false
19 |
20 | # Don't care if the mailer can't send
21 | config.action_mailer.raise_delivery_errors = false
22 |
23 | # Print deprecation notices to the Rails logger
24 | config.active_support.deprecation = :log
25 |
26 | # Only use best-standards-support built into browsers
27 | config.action_dispatch.best_standards_support = :builtin
28 |
29 | # Do not compress assets
30 | config.assets.compress = false
31 |
32 | # Expands the lines which load the assets
33 | config.assets.debug = true
34 | end
35 |
--------------------------------------------------------------------------------
/spec/dummy/db/migrate/20130817004307_move_admin_notes_to_comments.rb:
--------------------------------------------------------------------------------
1 | class MoveAdminNotesToComments < ActiveRecord::Migration
2 | def self.up
3 | remove_index :admin_notes, [:admin_user_type, :admin_user_id]
4 | rename_table :admin_notes, :active_admin_comments
5 | rename_column :active_admin_comments, :admin_user_type, :author_type
6 | rename_column :active_admin_comments, :admin_user_id, :author_id
7 | add_column :active_admin_comments, :namespace, :string
8 | add_index :active_admin_comments, [:namespace]
9 | add_index :active_admin_comments, [:author_type, :author_id]
10 |
11 | # Update all the existing comments to the default namespace
12 | say "Updating any existing comments to the #{ActiveAdmin.application.default_namespace} namespace."
13 | comments_table_name = ActiveRecord::Migrator.proper_table_name("active_admin_comments")
14 | execute "UPDATE #{comments_table_name} SET namespace='#{ActiveAdmin.application.default_namespace}'"
15 | end
16 |
17 | def self.down
18 | remove_index :active_admin_comments, :column => [:author_type, :author_id]
19 | remove_index :active_admin_comments, :column => [:namespace]
20 | remove_column :active_admin_comments, :namespace
21 | rename_column :active_admin_comments, :author_id, :admin_user_id
22 | rename_column :active_admin_comments, :author_type, :admin_user_type
23 | rename_table :active_admin_comments, :admin_notes
24 | add_index :admin_notes, [:admin_user_type, :admin_user_id]
25 | end
26 | end
27 |
--------------------------------------------------------------------------------
/spec/features/js_confirmation_spec.rb:
--------------------------------------------------------------------------------
1 | require 'spec_helper'
2 |
3 | feature "JS Confirmations" do
4 |
5 | given(:admin) { create(:user, super_admin: true) }
6 |
7 | given(:category) { create(:category, num_posts: 0) }
8 | given(:post) { create(:post, :reviewed, category: category) }
9 | given(:published_post) { create(:post, :published, category: category) }
10 |
11 | scenario 'accepting JS confirmation performs action', js: true do
12 | login_and_navigate_to_post admin, post
13 |
14 | message = accept_prompt do
15 | click_link("Publish Post")
16 | end
17 |
18 | expect(message).to eq("Do you want to publish now?")
19 | expect(page).to have_css(".flash.flash_notice", text: "Post successfully published")
20 |
21 | post_expect_have_workflow_state "published"
22 | end
23 |
24 | scenario 'rejecting JS confirmation skips action', js: true do
25 | login_and_navigate_to_post admin, post
26 |
27 | message = dismiss_prompt do
28 | click_link("Publish Post")
29 | end
30 |
31 | expect(message).to eq("Do you want to publish now?")
32 | expect(page).to_not have_css(".flash.flash_notice", text: "Post successfully published")
33 |
34 | post_expect_have_workflow_state "reviewed"
35 | end
36 |
37 | scenario 'JS prompt uses Proc for message', js: true do
38 | login_and_navigate_to_post admin, published_post
39 |
40 | message = accept_prompt do
41 | click_link("Archive")
42 | end
43 |
44 | expect(message).to eq("Do you want to archive?")
45 | post_expect_have_workflow_state "archived"
46 | end
47 | end
48 |
--------------------------------------------------------------------------------
/active_admin-workflow.gemspec:
--------------------------------------------------------------------------------
1 | $:.push File.expand_path("../lib", __FILE__)
2 |
3 | # Maintain your gem's version:
4 | require "active_admin/workflow/version"
5 |
6 | # Describe your gem and declare its dependencies:
7 | Gem::Specification.new do |s|
8 | s.name = "active_admin-workflow"
9 | s.version = ActiveAdmin::Workflow::VERSION
10 | s.authors = ["Quentin Rousseau"]
11 | s.email = ["contact@quent.in"]
12 | s.homepage = "https://github.com/kwent/active_admin-workflow"
13 | s.summary = "Provides easy DSL integration between ActiveAdmin & workflow"
14 | s.description = "Provides easy DSL integration between ActiveAdmin & workflow"
15 | s.license = "MIT"
16 |
17 | s.files = Dir["{app,config,db,lib}/**/*"] + ["MIT-LICENSE", "Rakefile", "README.md"]
18 | s.test_files = Dir["spec/**/*"]
19 |
20 | s.required_ruby_version = ">= 2.2"
21 |
22 | s.add_dependency "railties", ">= 4.2"
23 | s.add_dependency "activeadmin", ">= 1.0.0"
24 | s.add_dependency "workflow", ">= 1.0.0"
25 |
26 | s.add_development_dependency "rake"
27 | s.add_development_dependency "sqlite3"
28 | s.add_development_dependency "pg"
29 | s.add_development_dependency "rspec-rails"
30 | s.add_development_dependency "shoulda-matchers"
31 | s.add_development_dependency "puma"
32 | s.add_development_dependency "capybara"
33 | s.add_development_dependency "selenium-webdriver"
34 | s.add_development_dependency "webdrivers"
35 | s.add_development_dependency "database_cleaner"
36 | s.add_development_dependency "factory_bot_rails"
37 | s.add_development_dependency "devise"
38 | end
39 |
--------------------------------------------------------------------------------
/spec/dummy/config/environments/test.rb:
--------------------------------------------------------------------------------
1 | Dummy::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.
11 | config.eager_load = false
12 |
13 | # Configure static asset server for tests with Cache-Control for performance
14 | config.serve_static_files = true
15 | config.static_cache_control = "public, max-age=3600"
16 |
17 | # Log error messages when you accidentally call methods on nil
18 | config.whiny_nils = true
19 |
20 | # Show full error reports and disable caching
21 | config.consider_all_requests_local = true
22 | config.action_controller.perform_caching = false
23 |
24 | # Raise exceptions instead of rendering exception templates
25 | config.action_dispatch.show_exceptions = false
26 |
27 | # Disable request forgery protection in test environment
28 | config.action_controller.allow_forgery_protection = false
29 |
30 | # Tell Action Mailer not to deliver emails to the real world.
31 | # The :test delivery method accumulates sent emails in the
32 | # ActionMailer::Base.deliveries array.
33 | config.action_mailer.delivery_method = :test
34 |
35 | # Print deprecation notices to the stderr
36 | config.active_support.deprecation = :stderr
37 | end
38 |
--------------------------------------------------------------------------------
/spec/dummy/db/migrate/20130817004304_devise_create_admin_users.rb:
--------------------------------------------------------------------------------
1 | class DeviseCreateAdminUsers < ActiveRecord::Migration
2 | def migrate(direction)
3 | super
4 | # Create a default user
5 | AdminUser.create!(:email => 'admin@example.com', :password => 'password', :password_confirmation => 'password') if direction == :up
6 | end
7 |
8 | def change
9 | create_table(:admin_users) do |t|
10 | ## Database authenticatable
11 | t.string :email, :null => false, :default => ""
12 | t.string :encrypted_password, :null => false, :default => ""
13 |
14 | ## Recoverable
15 | t.string :reset_password_token
16 | t.datetime :reset_password_sent_at
17 |
18 | ## Rememberable
19 | t.datetime :remember_created_at
20 |
21 | ## Trackable
22 | t.integer :sign_in_count, :default => 0
23 | t.datetime :current_sign_in_at
24 | t.datetime :last_sign_in_at
25 | t.string :current_sign_in_ip
26 | t.string :last_sign_in_ip
27 |
28 | ## Confirmable
29 | # t.string :confirmation_token
30 | # t.datetime :confirmed_at
31 | # t.datetime :confirmation_sent_at
32 | # t.string :unconfirmed_email # Only if using reconfirmable
33 |
34 | ## Lockable
35 | # t.integer :failed_attempts, :default => 0 # Only if lock strategy is :failed_attempts
36 | # t.string :unlock_token # Only if unlock strategy is :email or :both
37 | # t.datetime :locked_at
38 |
39 | ## Token authenticatable
40 | # t.string :authentication_token
41 |
42 |
43 | t.timestamps
44 | end
45 |
46 | add_index :admin_users, :email, :unique => true
47 | add_index :admin_users, :reset_password_token, :unique => true
48 | # add_index :admin_users, :confirmation_token, :unique => true
49 | # add_index :admin_users, :unlock_token, :unique => true
50 | # add_index :admin_users, :authentication_token, :unique => true
51 | end
52 | end
53 |
--------------------------------------------------------------------------------
/spec/dummy/config/routes.rb:
--------------------------------------------------------------------------------
1 | Dummy::Application.routes.draw do
2 | devise_for :admin_users, ActiveAdmin::Devise.config
3 | ActiveAdmin.routes(self)
4 |
5 | # The priority is based upon order of creation:
6 | # first created -> highest priority.
7 |
8 | # Sample of regular route:
9 | # match 'products/:id' => 'catalog#view'
10 | # Keep in mind you can assign values other than :controller and :action
11 |
12 | # Sample of named route:
13 | # match 'products/:id/purchase' => 'catalog#purchase', :as => :purchase
14 | # This route can be invoked with purchase_url(:id => product.id)
15 |
16 | # Sample resource route (maps HTTP verbs to controller actions automatically):
17 | # resources :products
18 |
19 | # Sample resource route with options:
20 | # resources :products do
21 | # member do
22 | # get 'short'
23 | # post 'toggle'
24 | # end
25 | #
26 | # collection do
27 | # get 'sold'
28 | # end
29 | # end
30 |
31 | # Sample resource route with sub-resources:
32 | # resources :products do
33 | # resources :comments, :sales
34 | # resource :seller
35 | # end
36 |
37 | # Sample resource route with more complex sub-resources
38 | # resources :products do
39 | # resources :comments
40 | # resources :sales do
41 | # get 'recent', :on => :collection
42 | # end
43 | # end
44 |
45 | # Sample resource route within a namespace:
46 | # namespace :admin do
47 | # # Directs /admin/products/* to Admin::ProductsController
48 | # # (app/controllers/admin/products_controller.rb)
49 | # resources :products
50 | # end
51 |
52 | # You can have the root of your site routed with "root"
53 | # just remember to delete public/index.html.
54 | # root :to => 'welcome#index'
55 |
56 | # See how all your routes lay out with "rake routes"
57 |
58 | # This is a legacy wild controller route that's not recommended for RESTful applications.
59 | # Note: This route will make all actions in every controller accessible via GET requests.
60 | # match ':controller(/:action(/:id))(.:format)'
61 | end
62 |
--------------------------------------------------------------------------------
/lib/active_admin/workflow/dsl.rb:
--------------------------------------------------------------------------------
1 | module ActiveAdmin
2 | module Workflow
3 | module DSL
4 |
5 | #
6 | # Easily tie into a workflow action
7 | #
8 | # @param [Symbol] state machine event, ie: :publish
9 | # @param [Hash] options
10 | # - permission [Symbol] permission to check authorization against
11 | # - http_verb [Symbol] :put, :post, :get, etc
12 | #
13 | # Will call "resource.publish!", if "resource.can_publish?" returns true
14 | #
15 |
16 | def state_action(action, options={}, &controller_action)
17 | singular = config.resource_name.singular
18 | plural = config.resource_name.plural
19 |
20 | options[:permission] ||= controller.new.send(:action_to_permission, action)
21 | confirmation = options.fetch(:confirm, false)
22 | if confirmation == true
23 | default = "Are you sure you want to #{action.to_s.humanize.downcase}?"
24 | confirmation = ->{ I18n.t(:confirm, scope: "#{plural}.#{action}", default: default) }
25 | end
26 |
27 | http_verb = options.fetch :http_verb, :put
28 |
29 | action_item_args = if ActiveAdmin::VERSION.start_with?('0.')
30 | [{ only: :show }]
31 | else
32 | ["state_action_#{action}", { only: :show }]
33 | end
34 | action_item(*action_item_args) do
35 | if resource.send("can_#{action}?") && authorized?(options[:permission], resource)
36 | path = resource_path << "/#{action}"
37 | label = I18n.t("#{plural}.#{action}.label", default: action.to_s.titleize)
38 |
39 | link_options = {}
40 | if confirmation.is_a?(Proc)
41 | link_options[:data] ||= {}
42 | link_options[:data][:confirm] = instance_exec(&confirmation)
43 | end
44 |
45 | link_options[:class] = "btn btn-large"
46 | link_options[:method] = http_verb
47 |
48 | link_to label, path, link_options
49 | end
50 | end
51 |
52 | unless block_given?
53 | controller_action = -> do
54 | resource.send("#{action}!")
55 | flash[:notice] = t("#{plural}.#{action}.flash.success")
56 | redirect_to smart_resource_url
57 | end
58 | end
59 |
60 | member_action action, method: http_verb, &controller_action
61 | end
62 |
63 | end
64 | end
65 | end
66 |
--------------------------------------------------------------------------------
/spec/dummy/config/environments/production.rb:
--------------------------------------------------------------------------------
1 | Dummy::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 | # Do not eager load code on boot.
8 | config.eager_load = true
9 |
10 | # Full error reports are disabled and caching is turned on
11 | config.consider_all_requests_local = false
12 | config.action_controller.perform_caching = true
13 |
14 | # Disable Rails's static asset server (Apache or nginx will already do this)
15 | config.serve_static_files = false
16 |
17 | # Compress JavaScripts and CSS
18 | config.assets.compress = true
19 |
20 | # Don't fallback to assets pipeline if a precompiled asset is missed
21 | config.assets.compile = false
22 |
23 | # Generate digests for assets URLs
24 | config.assets.digest = true
25 |
26 | # Defaults to nil and saved in location specified by config.assets.prefix
27 | # config.assets.manifest = YOUR_PATH
28 |
29 | # Specifies the header that your server uses for sending files
30 | # config.action_dispatch.x_sendfile_header = "X-Sendfile" # for apache
31 | # config.action_dispatch.x_sendfile_header = 'X-Accel-Redirect' # for nginx
32 |
33 | # Force all access to the app over SSL, use Strict-Transport-Security, and use secure cookies.
34 | # config.force_ssl = true
35 |
36 | # See everything in the log (default is :info)
37 | # config.log_level = :debug
38 |
39 | # Prepend all log lines with the following tags
40 | # config.log_tags = [ :subdomain, :uuid ]
41 |
42 | # Use a different logger for distributed setups
43 | # config.logger = ActiveSupport::TaggedLogging.new(SyslogLogger.new)
44 |
45 | # Use a different cache store in production
46 | # config.cache_store = :mem_cache_store
47 |
48 | # Enable serving of images, stylesheets, and JavaScripts from an asset server
49 | # config.action_controller.asset_host = "http://assets.example.com"
50 |
51 | # Precompile additional assets (application.js, application.css, and all non-JS/CSS are already added)
52 | # config.assets.precompile += %w( search.js )
53 |
54 | # Disable delivery errors, bad email addresses will be ignored
55 | # config.action_mailer.raise_delivery_errors = false
56 |
57 | # Enable threaded mode
58 | # config.threadsafe!
59 |
60 | # Enable locale fallbacks for I18n (makes lookups for any locale fall back to
61 | # the I18n.default_locale when a translation can not be found)
62 | config.i18n.fallbacks = true
63 |
64 | # Send deprecation notices to registered listeners
65 | config.active_support.deprecation = :notify
66 | end
67 |
--------------------------------------------------------------------------------
/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 "sprockets/railtie"
8 | # require "rails/test_unit/railtie"
9 | require "devise"
10 |
11 | Bundler.require(*Rails.groups)
12 |
13 | module Dummy
14 | class Application < Rails::Application
15 | # Settings in config/environments/* take precedence over those specified here.
16 | # Application configuration should go into files in config/initializers
17 | # -- all .rb files in that directory are automatically loaded.
18 |
19 | # Custom directories with classes and modules you want to be autoloadable.
20 | # config.autoload_paths += %W(#{config.root}/extras)
21 |
22 | # Only load the plugins named here, in the order given (default is alphabetical).
23 | # :all can be used as a placeholder for all plugins not explicitly named.
24 | # config.plugins = [ :exception_notification, :ssl_requirement, :all ]
25 |
26 | # Activate observers that should always be running.
27 | # config.active_record.observers = :cacher, :garbage_collector, :forum_observer
28 |
29 | # Set Time.zone default to the specified zone and make Active Record auto-convert to this zone.
30 | # Run "rake -D time" for a list of tasks for finding time zone names. Default is UTC.
31 | # config.time_zone = 'Central Time (US & Canada)'
32 |
33 | # The default locale is :en and all translations from config/locales/*.rb,yml are auto loaded.
34 | # config.i18n.load_path += Dir[Rails.root.join('my', 'locales', '*.{rb,yml}').to_s]
35 | # config.i18n.default_locale = :de
36 |
37 | # Configure the default encoding used in templates for Ruby 1.9.
38 | config.encoding = "utf-8"
39 |
40 | # Configure sensitive parameters which will be filtered from the log file.
41 | config.filter_parameters += [:password]
42 |
43 | # Enable escaping HTML in JSON.
44 | config.active_support.escape_html_entities_in_json = true
45 |
46 | # Use SQL instead of Active Record's schema dumper when creating the database.
47 | # This is necessary if your schema can't be completely dumped by the schema dumper,
48 | # like if you have constraints or database-specific column types
49 | # config.active_record.schema_format = :sql
50 |
51 | # Enable the asset pipeline
52 | config.assets.enabled = true
53 |
54 | # Version of your assets, change this if you want to expire all your assets
55 | config.assets.version = '1.0'
56 |
57 | config.active_record.sqlite3.represent_boolean_as_integer = true
58 | end
59 | end
60 |
--------------------------------------------------------------------------------
/spec/dummy/db/schema.rb:
--------------------------------------------------------------------------------
1 | # This file is auto-generated from the current state of the database. Instead
2 | # of editing this file, please use the migrations feature of Active Record to
3 | # incrementally modify your database, and then regenerate this schema definition.
4 | #
5 | # Note that this schema.rb definition is the authoritative source for your
6 | # database schema. If you need to create the application database on another
7 | # system, you should be using db:schema:load, not running all the migrations
8 | # from scratch. The latter is a flawed and unsustainable approach (the more migrations
9 | # you'll amass, the slower it'll run and the greater likelihood for issues).
10 | #
11 | # It's strongly recommended that you check this file into your version control system.
12 |
13 | ActiveRecord::Schema.define(version: 2019_06_06_153623) do
14 |
15 | create_table "active_admin_comments", force: :cascade do |t|
16 | t.string "resource_id", null: false
17 | t.string "resource_type", null: false
18 | t.integer "author_id"
19 | t.string "author_type"
20 | t.text "body"
21 | t.datetime "created_at", null: false
22 | t.datetime "updated_at", null: false
23 | t.string "namespace"
24 | t.index ["author_type", "author_id"], name: "index_active_admin_comments_on_author_type_and_author_id"
25 | t.index ["namespace"], name: "index_active_admin_comments_on_namespace"
26 | t.index ["resource_type", "resource_id"], name: "index_admin_notes_on_resource_type_and_resource_id"
27 | end
28 |
29 | create_table "admin_users", force: :cascade do |t|
30 | t.string "email", default: "", null: false
31 | t.string "encrypted_password", default: "", null: false
32 | t.string "reset_password_token"
33 | t.datetime "reset_password_sent_at"
34 | t.datetime "remember_created_at"
35 | t.integer "sign_in_count", default: 0
36 | t.datetime "current_sign_in_at"
37 | t.datetime "last_sign_in_at"
38 | t.string "current_sign_in_ip"
39 | t.string "last_sign_in_ip"
40 | t.datetime "created_at", null: false
41 | t.datetime "updated_at", null: false
42 | t.boolean "super_admin", default: false
43 | t.index ["email"], name: "index_admin_users_on_email", unique: true
44 | t.index ["reset_password_token"], name: "index_admin_users_on_reset_password_token", unique: true
45 | end
46 |
47 | create_table "categories", force: :cascade do |t|
48 | t.string "name"
49 | t.datetime "created_at", null: false
50 | t.datetime "updated_at", null: false
51 | end
52 |
53 | create_table "posts", force: :cascade do |t|
54 | t.string "title", null: false
55 | t.text "body", null: false
56 | t.string "workflow_state", null: false
57 | t.datetime "created_at", null: false
58 | t.datetime "updated_at", null: false
59 | t.integer "category_id"
60 | end
61 |
62 | end
63 |
--------------------------------------------------------------------------------
/spec/spec_helper.rb:
--------------------------------------------------------------------------------
1 | # This file was generated by the `rspec --init` command. Conventionally, all
2 | # specs live under a `spec` directory, which RSpec adds to the `$LOAD_PATH`.
3 | # Require this file using `require "spec_helper"` to ensure that it is only
4 | # loaded once.
5 | #
6 | # See http://rubydoc.info/gems/rspec-core/RSpec/Core/Configuration
7 |
8 | $LOAD_PATH.unshift(File.dirname(__FILE__))
9 | ENV['RAILS_ENV'] ||= 'test'
10 |
11 | require File.expand_path("../dummy/config/environment.rb", __FILE__)
12 | require 'rspec/rails'
13 | require 'shoulda-matchers'
14 | require 'capybara/rails'
15 | require 'capybara/rspec'
16 | require 'selenium-webdriver'
17 | require 'webdrivers'
18 | require 'database_cleaner'
19 | require 'factory_bot'
20 |
21 | Capybara.register_driver :chrome do |app|
22 | Capybara::Selenium::Driver.new(app, browser: :chrome)
23 | end
24 |
25 | Capybara.register_driver :headless_chrome do |app|
26 | caps = Selenium::WebDriver::Remote::Capabilities.chrome(loggingPrefs: { browser: 'ALL' })
27 | opts = Selenium::WebDriver::Chrome::Options.new
28 |
29 | chrome_args = %w[--headless --window-size=1920,1080 --no-sandbox --disable-dev-shm-usage --enable-features=NetworkService,NetworkServiceInProcess]
30 | chrome_args.each { |arg| opts.add_argument(arg) }
31 | Capybara::Selenium::Driver.new(app, browser: :chrome, options: opts, desired_capabilities: caps)
32 | end
33 |
34 | Capybara.configure do |config|
35 | # change this to :chrome to observe tests in a real browser
36 | config.default_selector = :css
37 | config.javascript_driver = :headless_chrome
38 | end
39 |
40 |
41 | Rails.backtrace_cleaner.remove_silencers!
42 |
43 | # Load support files
44 | Dir["#{File.dirname(__FILE__)}/support/**/*.rb"].each { |f| require f }
45 |
46 | DatabaseCleaner.strategy = :truncation
47 |
48 | RSpec.configure do |config|
49 | config.run_all_when_everything_filtered = true
50 | config.mock_with :rspec
51 | config.infer_base_class_for_anonymous_controllers = false
52 |
53 |
54 | # Run specs in random order to surface order dependencies. If you find an
55 | # order dependency and want to debug it, you can fix the order by providing
56 | # the seed, which is printed after each run.
57 | # --seed 1234
58 | config.order = 'random'
59 |
60 | config.include Warden::Test::Helpers, type: :feature
61 | config.include FactoryBot::Syntax::Methods # Defines #create as FactoryBot.create
62 |
63 | config.before :all do
64 | FactoryBot.reload
65 | end
66 |
67 | config.before :each do
68 | DatabaseCleaner.clean_with :truncation
69 | end
70 |
71 | config.after(:each, :type => :feature) do
72 | DatabaseCleaner.clean # Truncate the database
73 | Capybara.reset_sessions! # Forget the (simulated) browser state
74 | Capybara.use_default_driver # Revert Capybara.current_driver to Capybara.default_driver
75 | end
76 | end
77 |
--------------------------------------------------------------------------------
/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 account was successfully confirmed. You are now signed in."
7 | send_instructions: "You will receive an email with instructions about how to confirm your account in a few minutes."
8 | send_paranoid_instructions: "If your email address exists in our database, you will receive an email with instructions about how to confirm your account in a few minutes."
9 | failure:
10 | already_authenticated: "You are already signed in."
11 | inactive: "Your account was not activated yet."
12 | invalid: "Invalid email or password."
13 | invalid_token: "Invalid authentication token."
14 | locked: "Your account is locked."
15 | not_found_in_database: "Invalid email 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 account 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 | omniauth_callbacks:
27 | failure: "Could not authenticate you from %{kind} because \"%{reason}\"."
28 | success: "Successfully authenticated from %{kind} account."
29 | passwords:
30 | 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."
31 | send_instructions: "You will receive an email with instructions about how to reset your password in a few minutes."
32 | 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."
33 | updated: "Your password was changed successfully. You are now signed in."
34 | updated_not_active: "Your password was changed successfully."
35 | registrations:
36 | destroyed: "Bye! Your account was successfully cancelled. We hope to see you again soon."
37 | signed_up: "Welcome! You have signed up successfully."
38 | signed_up_but_inactive: "You have signed up successfully. However, we could not sign you in because your account is not yet activated."
39 | signed_up_but_locked: "You have signed up successfully. However, we could not sign you in because your account is locked."
40 | signed_up_but_unconfirmed: "A message with a confirmation link has been sent to your email address. Please open the link to activate your account."
41 | update_needs_confirmation: "You updated your account successfully, but we need to verify your new email address. Please check your email and click on the confirm link to finalize confirming your new email address."
42 | updated: "You updated your account successfully."
43 | sessions:
44 | signed_in: "Signed in successfully."
45 | signed_out: "Signed out successfully."
46 | unlocks:
47 | send_instructions: "You will receive an email with instructions about how to unlock your account in a few minutes."
48 | send_paranoid_instructions: "If your account exists, you will receive an email with instructions about how to unlock it in a few minutes."
49 | unlocked: "Your account has been unlocked successfully. Please sign in to continue."
50 | errors:
51 | messages:
52 | already_confirmed: "was already confirmed, please try signing in"
53 | confirmation_period_expired: "needs to be confirmed within %{period}, please request a new one"
54 | expired: "has expired, please request a new one"
55 | not_found: "not found"
56 | not_locked: "was not locked"
57 | not_saved:
58 | one: "1 error prohibited this %{resource} from being saved:"
59 | other: "%{count} errors prohibited this %{resource} from being saved:"
60 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # ActiveAdmin-Workflow
2 |
3 | [](https://badge.fury.io/rb/active_admin-workflow)
4 | [](https://travis-ci.org/kwent/active_admin-workflow)
5 |
6 | This gem provides an easy integration between the awesome [workflow](https://github.com/geekq/workflow) and [active_admin](https://github.com/gregbell/active_admin) gems.
7 |
8 | ## Features
9 |
10 | This gem provides you with a DSL extension to ActiveAdmin that allows you to easily define action item buttons for your resource to transition through your workflow.
11 |
12 | * Integration with ActiveAdmin authorization adapater layer - the button won't show if the user isn't authorized
13 | * Provide custom permission to authorize against
14 | * Provide confirmation message to prompt user before performing
15 | * Button only shown if workflow can transition
16 | * Localizable button titles and flash messages
17 | * Pass a block to customize the behavior
18 |
19 | ## Installation
20 |
21 | This gem requires both `active_admin` and `workflow`. Add the gem to your Gemfile to get started and bundle.
22 |
23 | ```ruby
24 | gem 'active_admin-workflow'
25 | ```
26 |
27 | ## Usage
28 |
29 | You will need to define a workflow in a model, and have that model registered as a resource with ActiveAdmin.
30 |
31 | **A basic model**
32 |
33 | ```
34 | # app/models/post.rb
35 | class Post < ActiveRecord::Base
36 | include WorkflowActiverecord
37 |
38 | validates :title, presence: true, uniqueness: true
39 | validates :body, presence: true
40 |
41 | DRAFT = 'draft'
42 | REVIEWED = 'reviewed'
43 | PUBLISHED = 'published'
44 |
45 | workflow do
46 | state DRAFT do
47 | event :peer_review, transitions_to: REVIEWED
48 | end
49 | state REVIEWED do
50 | event :publish, transitions_to: PUBLISHED
51 | end
52 | state PUBLISHED do
53 | event :archive, transitions_to: ARCHIVED
54 | end
55 | end
56 | end
57 | ```
58 |
59 | **Corresponding ActiveAdmin resource**
60 |
61 | ```
62 | ActiveAdmin.register Post do
63 |
64 | state_action :peer_review
65 | state_action :publish
66 |
67 | form do |f|
68 | f.inputs "Post Details" do
69 | f.input :title
70 | f.input :body
71 | end
72 | f.actions
73 | end
74 |
75 | end
76 | ```
77 |
78 | In the above example, the `state_action` method is defined by this gem and provides you with the following functionality:
79 |
80 | 1. The `:peer_review` is assumed to be an event in your workflow definition on the Post model.
81 | 2. Calling `state_action` will add an action item button to your ActiveAdmin resource on the `#show` page, if the user is authorized to perform this action via the ActiveAdmin authorization adapter, and if the resource itself returns true to `#can_peer_review?`, which is provided by default with this event in workflow.
82 | 3. Clicking the button will call `#peer_review!` on the resource, and redirect you back to `smart_resource_url`.
83 | 4. Fully localizable, provide translations for `"posts.peer_review.label"`for the button title and `"posts.peer_review.flash.success` for the flash message when completed.
84 | 5. You can pass a block to customize this behavior.
85 |
86 | ### Custom Block
87 |
88 | ```
89 | ActiveAdmin.register Post do
90 |
91 | state_action :peer_review
92 |
93 | # Block to be called when submitted
94 | state_action :publish do
95 | PostPublicationService.publish!(resource)
96 | flash[:notice] = "Post published"
97 | redirect_to collection_path
98 | end
99 |
100 | end
101 | ```
102 |
103 | ### Custom Permission
104 |
105 | ```
106 | ActiveAdmin.register Post do
107 |
108 | # by default, permission would be :peer_review
109 | state_action :peer_review, permission: :read
110 | end
111 | ```
112 |
113 | ### Confirmation
114 |
115 | ```
116 | ActiveAdmin.register Post do
117 |
118 | # Lookup 'posts.peer_review.prompt'
119 | state_action :peer_review, confirm: :true
120 |
121 | # Pass proc
122 | state_action :peer_review, confirm: ->{ I18n.t("posts.peer_review.confirm") }
123 | end
124 | ```
125 |
126 | ### Using without workflow model
127 |
128 | If you really want to use without a workflow on your model, you essentially just need to provide the following methods, contining with our `:peer_review` example:
129 |
130 | ```
131 | class Post < ActiveRecord::Base
132 | def can_peer_review?
133 | author.present? && !published?
134 | end
135 |
136 | def peer_review!
137 | self.published_at = Time.now
138 | save!
139 | end
140 | end
141 | ```
142 |
143 | ## Credits
144 |
145 | Based on the amazing work of @macfanatic: https://github.com/macfanatic/active_admin-state_machine
146 |
--------------------------------------------------------------------------------
/spec/dummy/config/initializers/active_admin.rb:
--------------------------------------------------------------------------------
1 | ActiveAdmin.setup do |config|
2 |
3 | # == Site Title
4 | #
5 | # Set the title that is displayed on the main layout
6 | # for each of the active admin pages.
7 | #
8 | config.site_title = "Dummy"
9 |
10 | # Set the link url for the title. For example, to take
11 | # users to your main site. Defaults to no link.
12 | #
13 | # config.site_title_link = "/"
14 |
15 | # Set an optional image to be displayed for the header
16 | # instead of a string (overrides :site_title)
17 | #
18 | # Note: Recommended image height is 21px to properly fit in the header
19 | #
20 | # config.site_title_image = "/images/logo.png"
21 |
22 | # == Default Namespace
23 | #
24 | # Set the default namespace each administration resource
25 | # will be added to.
26 | #
27 | # eg:
28 | # config.default_namespace = :hello_world
29 | #
30 | # This will create resources in the HelloWorld module and
31 | # will namespace routes to /hello_world/*
32 | #
33 | # To set no namespace by default, use:
34 | # config.default_namespace = false
35 | #
36 | # Default:
37 | # config.default_namespace = :admin
38 | #
39 | # You can customize the settings for each namespace by using
40 | # a namespace block. For example, to change the site title
41 | # within a namespace:
42 | #
43 | # config.namespace :admin do |admin|
44 | # admin.site_title = "Custom Admin Title"
45 | # end
46 | #
47 | # This will ONLY change the title for the admin section. Other
48 | # namespaces will continue to use the main "site_title" configuration.
49 |
50 | # == User Authentication
51 | #
52 | # Active Admin will automatically call an authentication
53 | # method in a before filter of all controller actions to
54 | # ensure that there is a currently logged in admin user.
55 | #
56 | # This setting changes the method which Active Admin calls
57 | # within the controller.
58 | config.authentication_method = :authenticate_admin_user!
59 |
60 |
61 | # == Current User
62 | #
63 | # Active Admin will associate actions with the current
64 | # user performing them.
65 | #
66 | # This setting changes the method which Active Admin calls
67 | # to return the currently logged in user.
68 | config.current_user_method = :current_admin_user
69 |
70 |
71 | # == Logging Out
72 | #
73 | # Active Admin displays a logout link on each screen. These
74 | # settings configure the location and method used for the link.
75 | #
76 | # This setting changes the path where the link points to. If it's
77 | # a string, the strings is used as the path. If it's a Symbol, we
78 | # will call the method to return the path.
79 | #
80 | # Default:
81 | config.logout_link_path = :destroy_admin_user_session_path
82 |
83 | # This setting changes the http method used when rendering the
84 | # link. For example :get, :delete, :put, etc..
85 | #
86 | # Default:
87 | # config.logout_link_method = :get
88 |
89 | # == Root
90 | #
91 | # Set the action to call for the root path. You can set different
92 | # roots for each namespace.
93 | #
94 | # Default:
95 | # config.root_to = 'dashboard#index'
96 |
97 | # == Admin Comments
98 | #
99 | # Admin comments allow you to add comments to any model for admin use.
100 | # Admin comments are enabled by default.
101 | #
102 | # Default:
103 | config.comments = false
104 | #
105 | # You can turn them on and off for any given namespace by using a
106 | # namespace config block.
107 | #
108 | # Eg:
109 | # config.namespace :without_comments do |without_comments|
110 | # without_comments.allow_comments = false
111 | # end
112 |
113 |
114 | # == Batch Actions
115 | #
116 | # Enable and disable Batch Actions
117 | #
118 | config.batch_actions = true
119 |
120 |
121 | # == Controller Filters
122 | #
123 | # You can add before, after and around filters to all of your
124 | # Active Admin resources and pages from here.
125 | #
126 | # config.before_filter :do_something_awesome
127 |
128 |
129 | # == Register Stylesheets & Javascripts
130 | #
131 | # We recommend using the built in Active Admin layout and loading
132 | # up your own stylesheets / javascripts to customize the look
133 | # and feel.
134 | #
135 | # To load a stylesheet:
136 | # config.register_stylesheet 'my_stylesheet.css'
137 |
138 | # You can provide an options hash for more control, which is passed along to stylesheet_link_tag():
139 | # config.register_stylesheet 'my_print_stylesheet.css', :media => :print
140 | #
141 | # To load a javascript file:
142 | # config.register_javascript 'my_javascript.js'
143 |
144 |
145 | # == CSV options
146 | #
147 | # Set the CSV builder separator (default is ",")
148 | # config.csv_column_separator = ','
149 | #
150 | # Set the CSV builder options (default is {})
151 | # config.csv_options = {}
152 |
153 |
154 | # == Menu System
155 | #
156 | # You can add a navigation menu to be used in your application, or configure a provided menu
157 | #
158 | # To change the default utility navigation to show a link to your website & a logout btn
159 | #
160 | # config.namespace :admin do |admin|
161 | # admin.build_menu :utility_navigation do |menu|
162 | # menu.add label: "My Great Website", url: "http://www.mygreatwebsite.com", html_options: { target: :blank }
163 | # admin.add_logout_button_to_menu menu
164 | # end
165 | # end
166 | #
167 | # If you wanted to add a static menu item to the default menu provided:
168 | #
169 | # config.namespace :admin do |admin|
170 | # admin.build_menu :default do |menu|
171 | # menu.add label: "My Great Website", url: "http://www.mygreatwebsite.com", html_options: { target: :blank }
172 | # end
173 | # end
174 |
175 | # == Download Links
176 | #
177 | # You can disable download links on resource listing pages,
178 | # or customize the formats shown per namespace/globally
179 | #
180 | # To disable/customize for the :admin namespace:
181 | #
182 | # config.namespace :admin do |admin|
183 | #
184 | # # Disable the links entirely
185 | # admin.download_links = false
186 | #
187 | # # Only show XML & PDF options
188 | # admin.download_links = [:xml, :pdf]
189 | #
190 | # end
191 |
192 |
193 | # == Pagination
194 | #
195 | # Pagination is enabled by default for all resources.
196 | # You can control the default per page count for all resources here.
197 | #
198 | # config.default_per_page = 30
199 |
200 |
201 | # == Filters
202 | #
203 | # By default the index screen includes a “Filters” sidebar on the right
204 | # hand side with a filter for each attribute of the registered model.
205 | # You can enable or disable them for all resources here.
206 | #
207 | # config.filters = true
208 |
209 | config.authorization_adapter = "ActiveAdmin::CanCanAdapter"
210 |
211 | end
212 |
--------------------------------------------------------------------------------
/spec/dummy/README.rdoc:
--------------------------------------------------------------------------------
1 | == Welcome to Rails
2 |
3 | Rails is a web-application framework that includes everything needed to create
4 | database-backed web applications according to the Model-View-Control pattern.
5 |
6 | This pattern splits the view (also called the presentation) into "dumb"
7 | templates that are primarily responsible for inserting pre-built data in between
8 | HTML tags. The model contains the "smart" domain objects (such as Account,
9 | Product, Person, Post) that holds all the business logic and knows how to
10 | persist themselves to a database. The controller handles the incoming requests
11 | (such as Save New Account, Update Product, Show Post) by manipulating the model
12 | and directing data to the view.
13 |
14 | In Rails, the model is handled by what's called an object-relational mapping
15 | layer entitled Active Record. This layer allows you to present the data from
16 | database rows as objects and embellish these data objects with business logic
17 | methods. You can read more about Active Record in
18 | link:files/vendor/rails/activerecord/README.html.
19 |
20 | The controller and view are handled by the Action Pack, which handles both
21 | layers by its two parts: Action View and Action Controller. These two layers
22 | are bundled in a single package due to their heavy interdependence. This is
23 | unlike the relationship between the Active Record and Action Pack that is much
24 | more separate. Each of these packages can be used independently outside of
25 | Rails. You can read more about Action Pack in
26 | link:files/vendor/rails/actionpack/README.html.
27 |
28 |
29 | == Getting Started
30 |
31 | 1. At the command prompt, create a new Rails application:
32 | rails new myapp (where myapp is the application name)
33 |
34 | 2. Change directory to myapp and start the web server:
35 | cd myapp; rails server (run with --help for options)
36 |
37 | 3. Go to http://localhost:3000/ and you'll see:
38 | "Welcome aboard: You're riding Ruby on Rails!"
39 |
40 | 4. Follow the guidelines to start developing your application. You can find
41 | the following resources handy:
42 |
43 | * The Getting Started Guide: http://guides.rubyonrails.org/getting_started.html
44 | * Ruby on Rails Tutorial Book: http://www.railstutorial.org/
45 |
46 |
47 | == Debugging Rails
48 |
49 | Sometimes your application goes wrong. Fortunately there are a lot of tools that
50 | will help you debug it and get it back on the rails.
51 |
52 | First area to check is the application log files. Have "tail -f" commands
53 | running on the server.log and development.log. Rails will automatically display
54 | debugging and runtime information to these files. Debugging info will also be
55 | shown in the browser on requests from 127.0.0.1.
56 |
57 | You can also log your own messages directly into the log file from your code
58 | using the Ruby logger class from inside your controllers. Example:
59 |
60 | class WeblogController < ActionController::Base
61 | def destroy
62 | @weblog = Weblog.find(params[:id])
63 | @weblog.destroy
64 | logger.info("#{Time.now} Destroyed Weblog ID ##{@weblog.id}!")
65 | end
66 | end
67 |
68 | The result will be a message in your log file along the lines of:
69 |
70 | Mon Oct 08 14:22:29 +1000 2007 Destroyed Weblog ID #1!
71 |
72 | More information on how to use the logger is at http://www.ruby-doc.org/core/
73 |
74 | Also, Ruby documentation can be found at http://www.ruby-lang.org/. There are
75 | several books available online as well:
76 |
77 | * Programming Ruby: http://www.ruby-doc.org/docs/ProgrammingRuby/ (Pickaxe)
78 | * Learn to Program: http://pine.fm/LearnToProgram/ (a beginners guide)
79 |
80 | These two books will bring you up to speed on the Ruby language and also on
81 | programming in general.
82 |
83 |
84 | == Debugger
85 |
86 | Debugger support is available through the debugger command when you start your
87 | Mongrel or WEBrick server with --debugger. This means that you can break out of
88 | execution at any point in the code, investigate and change the model, and then,
89 | resume execution! You need to install ruby-debug to run the server in debugging
90 | mode. With gems, use sudo gem install ruby-debug. Example:
91 |
92 | class WeblogController < ActionController::Base
93 | def index
94 | @posts = Post.all
95 | debugger
96 | end
97 | end
98 |
99 | So the controller will accept the action, run the first line, then present you
100 | with a IRB prompt in the server window. Here you can do things like:
101 |
102 | >> @posts.inspect
103 | => "[#nil, "body"=>nil, "id"=>"1"}>,
105 | #"Rails", "body"=>"Only ten..", "id"=>"2"}>]"
107 | >> @posts.first.title = "hello from a debugger"
108 | => "hello from a debugger"
109 |
110 | ...and even better, you can examine how your runtime objects actually work:
111 |
112 | >> f = @posts.first
113 | => #nil, "body"=>nil, "id"=>"1"}>
114 | >> f.
115 | Display all 152 possibilities? (y or n)
116 |
117 | Finally, when you're ready to resume execution, you can enter "cont".
118 |
119 |
120 | == Console
121 |
122 | The console is a Ruby shell, which allows you to interact with your
123 | application's domain model. Here you'll have all parts of the application
124 | configured, just like it is when the application is running. You can inspect
125 | domain models, change values, and save to the database. Starting the script
126 | without arguments will launch it in the development environment.
127 |
128 | To start the console, run rails console from the application
129 | directory.
130 |
131 | Options:
132 |
133 | * Passing the -s, --sandbox argument will rollback any modifications
134 | made to the database.
135 | * Passing an environment name as an argument will load the corresponding
136 | environment. Example: rails console production.
137 |
138 | To reload your controllers and models after launching the console run
139 | reload!
140 |
141 | More information about irb can be found at:
142 | link:http://www.rubycentral.org/pickaxe/irb.html
143 |
144 |
145 | == dbconsole
146 |
147 | You can go to the command line of your database directly through rails
148 | dbconsole. You would be connected to the database with the credentials
149 | defined in database.yml. Starting the script without arguments will connect you
150 | to the development database. Passing an argument will connect you to a different
151 | database, like rails dbconsole production. Currently works for MySQL,
152 | PostgreSQL and SQLite 3.
153 |
154 | == Description of Contents
155 |
156 | The default directory structure of a generated Ruby on Rails application:
157 |
158 | |-- app
159 | | |-- assets
160 | | | |-- images
161 | | | |-- javascripts
162 | | | `-- stylesheets
163 | | |-- controllers
164 | | |-- helpers
165 | | |-- mailers
166 | | |-- models
167 | | `-- views
168 | | `-- layouts
169 | |-- config
170 | | |-- environments
171 | | |-- initializers
172 | | `-- locales
173 | |-- db
174 | |-- doc
175 | |-- lib
176 | | |-- assets
177 | | `-- tasks
178 | |-- log
179 | |-- public
180 | |-- script
181 | |-- test
182 | | |-- fixtures
183 | | |-- functional
184 | | |-- integration
185 | | |-- performance
186 | | `-- unit
187 | |-- tmp
188 | | `-- cache
189 | | `-- assets
190 | `-- vendor
191 | |-- assets
192 | | |-- javascripts
193 | | `-- stylesheets
194 | `-- plugins
195 |
196 | app
197 | Holds all the code that's specific to this particular application.
198 |
199 | app/assets
200 | Contains subdirectories for images, stylesheets, and JavaScript files.
201 |
202 | app/controllers
203 | Holds controllers that should be named like weblogs_controller.rb for
204 | automated URL mapping. All controllers should descend from
205 | ApplicationController which itself descends from ActionController::Base.
206 |
207 | app/models
208 | Holds models that should be named like post.rb. Models descend from
209 | ActiveRecord::Base by default.
210 |
211 | app/views
212 | Holds the template files for the view that should be named like
213 | weblogs/index.html.erb for the WeblogsController#index action. All views use
214 | eRuby syntax by default.
215 |
216 | app/views/layouts
217 | Holds the template files for layouts to be used with views. This models the
218 | common header/footer method of wrapping views. In your views, define a layout
219 | using the layout :default and create a file named default.html.erb.
220 | Inside default.html.erb, call <% yield %> to render the view using this
221 | layout.
222 |
223 | app/helpers
224 | Holds view helpers that should be named like weblogs_helper.rb. These are
225 | generated for you automatically when using generators for controllers.
226 | Helpers can be used to wrap functionality for your views into methods.
227 |
228 | config
229 | Configuration files for the Rails environment, the routing map, the database,
230 | and other dependencies.
231 |
232 | db
233 | Contains the database schema in schema.rb. db/migrate contains all the
234 | sequence of Migrations for your schema.
235 |
236 | doc
237 | This directory is where your application documentation will be stored when
238 | generated using rake doc:app
239 |
240 | lib
241 | Application specific libraries. Basically, any kind of custom code that
242 | doesn't belong under controllers, models, or helpers. This directory is in
243 | the load path.
244 |
245 | public
246 | The directory available for the web server. Also contains the dispatchers and the
247 | default HTML files. This should be set as the DOCUMENT_ROOT of your web
248 | server.
249 |
250 | script
251 | Helper scripts for automation and generation.
252 |
253 | test
254 | Unit and functional tests along with fixtures. When using the rails generate
255 | command, template test files will be generated for you and placed in this
256 | directory.
257 |
258 | vendor
259 | External libraries that the application depends on. Also includes the plugins
260 | subdirectory. If the app has frozen rails, those gems also go here, under
261 | vendor/rails/. This directory is in the load path.
262 |
--------------------------------------------------------------------------------
/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 | config.secret_key = '90f7a6fb644a98cb3a5231195727454b881befcad005721f0bb007b0b8d1a794b933eb89f19a9269e98e8a613541b82973318ac2781551cb4d1a01cee388c7c7'
5 | # ==> Mailer Configuration
6 | # Configure the e-mail address which will be shown in Devise::Mailer,
7 | # note that it will be overwritten if you use your own mailer class with default "from" parameter.
8 | config.mailer_sender = "please-change-me-at-config-initializers-devise@example.com"
9 |
10 | # Configure the class responsible to send e-mails.
11 | # config.mailer = "Devise::Mailer"
12 |
13 | # ==> ORM configuration
14 | # Load and configure the ORM. Supports :active_record (default) and
15 | # :mongoid (bson_ext recommended) by default. Other ORMs may be
16 | # available as additional gems.
17 | require 'devise/orm/active_record'
18 |
19 | # ==> Configuration for any authentication mechanism
20 | # Configure which keys are used when authenticating a user. The default is
21 | # just :email. You can configure it to use [:username, :subdomain], so for
22 | # authenticating a user, both parameters are required. Remember that those
23 | # parameters are used only when authenticating and not when retrieving from
24 | # session. If you need permissions, you should implement that in a before filter.
25 | # You can also supply a hash where the value is a boolean determining whether
26 | # or not authentication should be aborted when the value is not present.
27 | # config.authentication_keys = [ :email ]
28 |
29 | # Configure parameters from the request object used for authentication. Each entry
30 | # given should be a request method and it will automatically be passed to the
31 | # find_for_authentication method and considered in your model lookup. For instance,
32 | # if you set :request_keys to [:subdomain], :subdomain will be used on authentication.
33 | # The same considerations mentioned for authentication_keys also apply to request_keys.
34 | # config.request_keys = []
35 |
36 | # Configure which authentication keys should be case-insensitive.
37 | # These keys will be downcased upon creating or modifying a user and when used
38 | # to authenticate or find a user. Default is :email.
39 | config.case_insensitive_keys = [ :email ]
40 |
41 | # Configure which authentication keys should have whitespace stripped.
42 | # These keys will have whitespace before and after removed upon creating or
43 | # modifying a user and when used to authenticate or find a user. Default is :email.
44 | config.strip_whitespace_keys = [ :email ]
45 |
46 | # Tell if authentication through request.params is enabled. True by default.
47 | # It can be set to an array that will enable params authentication only for the
48 | # given strategies, for example, `config.params_authenticatable = [:database]` will
49 | # enable it only for database (email + password) authentication.
50 | # config.params_authenticatable = true
51 |
52 | # Tell if authentication through HTTP Auth is enabled. False by default.
53 | # It can be set to an array that will enable http authentication only for the
54 | # given strategies, for example, `config.http_authenticatable = [:token]` will
55 | # enable it only for token authentication. The supported strategies are:
56 | # :database = Support basic authentication with authentication key + password
57 | # :token = Support basic authentication with token authentication key
58 | # :token_options = Support token authentication with options as defined in
59 | # http://api.rubyonrails.org/classes/ActionController/HttpAuthentication/Token.html
60 | # config.http_authenticatable = false
61 |
62 | # If http headers should be returned for AJAX requests. True by default.
63 | # config.http_authenticatable_on_xhr = true
64 |
65 | # The realm used in Http Basic Authentication. "Application" by default.
66 | # config.http_authentication_realm = "Application"
67 |
68 | # It will change confirmation, password recovery and other workflows
69 | # to behave the same regardless if the e-mail provided was right or wrong.
70 | # Does not affect registerable.
71 | # config.paranoid = true
72 |
73 | # By default Devise will store the user in session. You can skip storage for
74 | # :http_auth and :token_auth by adding those symbols to the array below.
75 | # Notice that if you are skipping storage for all authentication paths, you
76 | # may want to disable generating routes to Devise's sessions controller by
77 | # passing :skip => :sessions to `devise_for` in your config/routes.rb
78 | config.skip_session_storage = [:http_auth]
79 |
80 | # By default, Devise cleans up the CSRF token on authentication to
81 | # avoid CSRF token fixation attacks. This means that, when using AJAX
82 | # requests for sign in and sign up, you need to get a new CSRF token
83 | # from the server. You can disable this option at your own risk.
84 | # config.clean_up_csrf_token_on_authentication = true
85 |
86 | # ==> Configuration for :database_authenticatable
87 | # For bcrypt, this is the cost for hashing the password and defaults to 10. If
88 | # using other encryptors, it sets how many times you want the password re-encrypted.
89 | #
90 | # Limiting the stretches to just one in testing will increase the performance of
91 | # your test suite dramatically. However, it is STRONGLY RECOMMENDED to not use
92 | # a value less than 10 in other environments.
93 | config.stretches = Rails.env.test? ? 1 : 10
94 |
95 | # Setup a pepper to generate the encrypted password.
96 | # config.pepper = "2d9d8c21cb198f569399a5550cd5dda1bbcfb25865926070a6f31c42f0d8447f99f00c935ca1fca7ca0493a2060b4053f1990fcc3be195e5f7fabeb004f344b5"
97 |
98 | # ==> Configuration for :confirmable
99 | # A period that the user is allowed to access the website even without
100 | # confirming his account. For instance, if set to 2.days, the user will be
101 | # able to access the website for two days without confirming his account,
102 | # access will be blocked just in the third day. Default is 0.days, meaning
103 | # the user cannot access the website without confirming his account.
104 | # config.allow_unconfirmed_access_for = 2.days
105 |
106 | # A period that the user is allowed to confirm their account before their
107 | # token becomes invalid. For example, if set to 3.days, the user can confirm
108 | # their account within 3 days after the mail was sent, but on the fourth day
109 | # their account can't be confirmed with the token any more.
110 | # Default is nil, meaning there is no restriction on how long a user can take
111 | # before confirming their account.
112 | # config.confirm_within = 3.days
113 |
114 | # If true, requires any email changes to be confirmed (exactly the same way as
115 | # initial account confirmation) to be applied. Requires additional unconfirmed_email
116 | # db field (see migrations). Until confirmed new email is stored in
117 | # unconfirmed email column, and copied to email column on successful confirmation.
118 | config.reconfirmable = true
119 |
120 | # Defines which key will be used when confirming an account
121 | # config.confirmation_keys = [ :email ]
122 |
123 | # ==> Configuration for :rememberable
124 | # The time the user will be remembered without asking for credentials again.
125 | # config.remember_for = 2.weeks
126 |
127 | # If true, extends the user's remember period when remembered via cookie.
128 | # config.extend_remember_period = false
129 |
130 | # Options to be passed to the created cookie. For instance, you can set
131 | # :secure => true in order to force SSL only cookies.
132 | # config.rememberable_options = {}
133 |
134 | # ==> Configuration for :validatable
135 | # Range for password length. Default is 8..128.
136 | config.password_length = 8..128
137 |
138 | # Email regex used to validate email formats. It simply asserts that
139 | # one (and only one) @ exists in the given string. This is mainly
140 | # to give user feedback and not to assert the e-mail validity.
141 | # config.email_regexp = /\A[^@]+@[^@]+\z/
142 |
143 | # ==> Configuration for :timeoutable
144 | # The time you want to timeout the user session without activity. After this
145 | # time the user will be asked for credentials again. Default is 30 minutes.
146 | # config.timeout_in = 30.minutes
147 |
148 | # If true, expires auth token on session timeout.
149 | # config.expire_auth_token_on_timeout = false
150 |
151 | # ==> Configuration for :lockable
152 | # Defines which strategy will be used to lock an account.
153 | # :failed_attempts = Locks an account after a number of failed attempts to sign in.
154 | # :none = No lock strategy. You should handle locking by yourself.
155 | # config.lock_strategy = :failed_attempts
156 |
157 | # Defines which key will be used when locking and unlocking an account
158 | # config.unlock_keys = [ :email ]
159 |
160 | # Defines which strategy will be used to unlock an account.
161 | # :email = Sends an unlock link to the user email
162 | # :time = Re-enables login after a certain amount of time (see :unlock_in below)
163 | # :both = Enables both strategies
164 | # :none = No unlock strategy. You should handle unlocking by yourself.
165 | # config.unlock_strategy = :both
166 |
167 | # Number of authentication tries before locking an account if lock_strategy
168 | # is failed attempts.
169 | # config.maximum_attempts = 20
170 |
171 | # Time interval to unlock the account if :time is enabled as unlock_strategy.
172 | # config.unlock_in = 1.hour
173 |
174 | # ==> Configuration for :recoverable
175 | #
176 | # Defines which key will be used when recovering the password for an account
177 | # config.reset_password_keys = [ :email ]
178 |
179 | # Time interval you can reset your password with a reset password key.
180 | # Don't put a too small interval or your users won't have the time to
181 | # change their passwords.
182 | config.reset_password_within = 6.hours
183 |
184 | # ==> Configuration for :encryptable
185 | # Allow you to use another encryption algorithm besides bcrypt (default). You can use
186 | # :sha1, :sha512 or encryptors from others authentication tools as :clearance_sha1,
187 | # :authlogic_sha512 (then you should set stretches above to 20 for default behavior)
188 | # and :restful_authentication_sha1 (then you should set stretches to 10, and copy
189 | # REST_AUTH_SITE_KEY to pepper).
190 | #
191 | # Require the `devise-encryptable` gem when using anything other than bcrypt
192 | # config.encryptor = :sha512
193 |
194 | # ==> Configuration for :token_authenticatable
195 | # Defines name of the authentication token params key
196 | # config.token_authentication_key = :auth_token
197 |
198 | # ==> Scopes configuration
199 | # Turn scoped views on. Before rendering "sessions/new", it will first check for
200 | # "users/sessions/new". It's turned off by default because it's slower if you
201 | # are using only default views.
202 | # config.scoped_views = false
203 |
204 | # Configure the default scope given to Warden. By default it's the first
205 | # devise role declared in your routes (usually :user).
206 | # config.default_scope = :user
207 |
208 | # Set this configuration to false if you want /users/sign_out to sign out
209 | # only the current scope. By default, Devise signs out all scopes.
210 | # config.sign_out_all_scopes = true
211 |
212 | # ==> Navigation configuration
213 | # Lists the formats that should be treated as navigational. Formats like
214 | # :html, should redirect to the sign in page when the user does not have
215 | # access, but formats like :xml or :json, should return 401.
216 | #
217 | # If you have any extra navigational formats, like :iphone or :mobile, you
218 | # should add them to the navigational formats lists.
219 | #
220 | # The "*/*" below is required to match Internet Explorer requests.
221 | # config.navigational_formats = ["*/*", :html]
222 |
223 | # The default HTTP method used to sign out a resource. Default is :delete.
224 | config.sign_out_via = :delete
225 |
226 | # ==> OmniAuth
227 | # Add a new OmniAuth provider. Check the wiki for more information on setting
228 | # up on your models and hooks.
229 | # config.omniauth :github, 'APP_ID', 'APP_SECRET', :scope => 'user,public_repo'
230 |
231 | # ==> Warden configuration
232 | # If you want to use other strategies, that are not supported by Devise, or
233 | # change the failure app, you can configure them inside the config.warden block.
234 | #
235 | # config.warden do |manager|
236 | # manager.intercept_401 = false
237 | # manager.default_strategies(:scope => :user).unshift :some_external_strategy
238 | # end
239 |
240 | # ==> Mountable engine configurations
241 | # When using Devise inside an engine, let's call it `MyEngine`, and this engine
242 | # is mountable, there are some extra configurations to be taken into account.
243 | # The following options are available, assuming the engine is mounted as:
244 | #
245 | # mount MyEngine, at: "/my_engine"
246 | #
247 | # The router that invoked `devise_for`, in the example above, would be:
248 | # config.router_name = :my_engine
249 | #
250 | # When using omniauth, Devise cannot automatically set Omniauth path,
251 | # so you need to do it manually. For the users scope, it would be:
252 | # config.omniauth_path_prefix = "/my_engine/users/auth"
253 | end
254 |
--------------------------------------------------------------------------------