diff --git a/README.md b/README.md index b4a8e72caf..f8aa9f2785 100644 --- a/README.md +++ b/README.md @@ -28,26 +28,19 @@ RailsAdmin is a Rails engine that provides an easy-to-use interface for managing * ActiveRecord * Mongoid -## Installation -After you bundled the gem, mount RailsAdmin gem in `config/routes.rb`: -```ruby -mount RailsAdmin::Engine => '/admin', :as => 'rails_admin' # Change '/admin' to any namespace you like. -``` -Start a server `rails s` and administer your data at [/admin](http://localhost:3000/admin). +## Installation + +1. Bundle the gem +2. Run `rails g rails_admin:install` +3. Provide a namespace for the routes when asked +4. Start a server `rails s` and administer your data at [/admin](http://localhost:3000/admin). (if you chose default namespace: /admin) ## Configuration ### Global In `config/initializers/rails_admin`: -```ruby -RailsAdmin.config do |config| - config.main_app_name = ["Cool app", "BackOffice"] - # ... -end -``` - [Details](https://github.com/sferik/rails_admin/wiki/Base-configuration) To begin with, you may be interested in setting up [Devise](https://github.com/sferik/rails_admin/wiki/Devise), [Cancan](https://github.com/sferik/rails_admin/wiki/Cancan) or [Papertrail](https://github.com/sferik/rails_admin/wiki/Papertrail)! diff --git a/lib/generators/rails_admin/install_generator.rb b/lib/generators/rails_admin/install_generator.rb index d6d5d9f412..f9d5fd0968 100644 --- a/lib/generators/rails_admin/install_generator.rb +++ b/lib/generators/rails_admin/install_generator.rb @@ -1,97 +1,18 @@ require 'rails/generators' require File.expand_path('../utils', __FILE__) -# http://guides.rubyonrails.org/generators.html -# http://rdoc.info/github/wycats/thor/master/Thor/Actions.html -# keep generator idempotent, thanks - module RailsAdmin class InstallGenerator < Rails::Generators::Base source_root File.expand_path("../templates", __FILE__) - include Rails::Generators::Migration include Generators::Utils::InstanceMethods - extend Generators::Utils::ClassMethods - class_option :skip_devise, :type => :boolean, :aliases => '-D', - :desc => "Skip installation and setup of devise gem." - argument :_model_name, :type => :string, :required => false, :desc => "Devise user model name" argument :_namespace, :type => :string, :required => false, :desc => "RailsAdmin url namespace" desc "RailsAdmin installation generator" def install - routes = File.open(Rails.root.join("config/routes.rb")).try :read - initializer = (File.open(Rails.root.join("config/initializers/rails_admin.rb")) rescue nil).try :read - - display "Hello, RailsAdmin installer will help you set things up!", :blue - display "I need to work with Devise, let's look at a few things first:" - if options[:skip_devise] - display "Skipping devise installation..." - else - display "Checking for a current installation of devise..." - unless defined?(Devise) - display "Adding devise gem to your Gemfile:" - append_file "Gemfile", "\n", :force => true - gem 'devise' - Bundler.with_clean_env do - run "bundle install" - end - else - display "Found it!" - end - unless File.exists?(Rails.root.join("config/initializers/devise.rb")) - display "Looks like you don't have devise installed! We'll install it for you:" - generate "devise:install" - else - display "Looks like you've already installed it, good!" - end - end - namespace = ask_for("Where do you want to mount rails_admin?", "admin", _namespace) - gsub_file "config/routes.rb", /mount RailsAdmin::Engine => \'\/.+\', :as => \'rails_admin\'/, '' route("mount RailsAdmin::Engine => '/#{namespace}', :as => 'rails_admin'") - - unless options[:skip_devise] - unless routes.index("devise_for") - model_name = ask_for("What would you like the user model to be called?", "user", _model_name) - display "Now setting up devise with user model name '#{model_name}':" - generate "devise", model_name - else - display "And you already set it up, good! We just need to know about your user model name..." - guess = routes.match(/devise_for +:(\w+)/)[1].try(:singularize) - display("We found '#{guess}' (should be one of 'user', 'admin', etc.)") - model_name = ask_for("Correct Devise model name if needed.", guess, _model_name) - unless guess == model_name - display "Now setting up devise with user model name '#{model_name}':" - generate "devise", model_name - else - display "Ok, Devise looks already set up with user model name '#{model_name}':" - end - end - end - display "Now you'll need an initializer..." - @current_user_method = model_name ? "current_#{model_name.to_s.underscore}" : "" - @model_name = model_name || '' - unless initializer - template "initializer.erb", "config/initializers/rails_admin.rb" - else - display "You already have a config file. You're updating, heh? I'm generating a new 'rails_admin.rb.example' that you can review." - template "initializer.erb", "config/initializers/rails_admin.rb.example" - config_tag = initializer.match(/RailsAdmin\.config.+\|(.+)\|/)[1] rescue nil - if config_tag - if initializer.index(::Regexp.new("#{config_tag}\.current_user_method.?\{.+?\}")) - display "current_user_method found and updated with '#{@current_user_method}'", :green - gsub_file Rails.root.join("config/initializers/rails_admin.rb"), ::Regexp.new("#{config_tag}\.current_user_method.?\{.+?\}"), "#{config_tag}.current_user_method { #{@current_user_method} }" - else - display "current_user_method not found. Added one with '#{@current_user_method}'!", :yellow - insert_into_file Rails.root.join("config/initializers/rails_admin.rb"), "\n\n #{config_tag}.current_user_method { #{@current_user_method} } #auto-generated", :after => /^RailsAdmin\.config.+$/ - end - else - display "Couldn't parse your config file: current_user_method couldn't be updated", :red - end - end - display "Adding a migration..." - migration_template 'migration.rb', 'db/migrate/create_rails_admin_histories_table.rb' rescue display $!.message - display "Job's done: migrate, start your server and visit '/#{namespace}'!", :blue + template "initializer.erb", "config/initializers/rails_admin.rb" end end end diff --git a/lib/generators/rails_admin/templates/drop.rb b/lib/generators/rails_admin/templates/drop.rb deleted file mode 100644 index 270ece9176..0000000000 --- a/lib/generators/rails_admin/templates/drop.rb +++ /dev/null @@ -1,18 +0,0 @@ -class DropRailsAdminHistoriesTable < ActiveRecord::Migration - def self.up - drop_table :rails_admin_histories - end - - def self.down - create_table :rails_admin_histories do |t| - t.text :message # title, name, or object_id - t.string :username - t.integer :item - t.string :table - t.integer :month, :limit => 2 - t.integer :year, :limit => 5 - t.timestamps - end - add_index(:rails_admin_histories, [:item, :table, :month, :year], :name => 'index_rails_admin_histories' ) - end -end diff --git a/lib/generators/rails_admin/templates/initializer.erb b/lib/generators/rails_admin/templates/initializer.erb index 0b8e5a7d99..bc4179a480 100644 --- a/lib/generators/rails_admin/templates/initializer.erb +++ b/lib/generators/rails_admin/templates/initializer.erb @@ -1,100 +1,34 @@ -# RailsAdmin config file. Generated on <%= DateTime.now.to_s(:long) %> -# See github.com/sferik/rails_admin for more informations - RailsAdmin.config do |config| + ### Popular gems integration - ################ Global configuration ################ - - # Set the admin name here (optional second array element will appear in red). For example: - config.main_app_name = ['<%= Rails.application.engine_name.titleize.chomp(' Application') %>', 'Admin'] - # or for a more dynamic name: - # config.main_app_name = Proc.new { |controller| [Rails.application.engine_name.titleize, controller.params['action'].titleize] } - - # RailsAdmin may need a way to know who the current user is] - config.current_user_method { <%= @current_user_method %> } # auto-generated - - # If you want to track changes on your models: - # config.audit_with :history, '<%= @model_name.classify %>' - - # Or with a PaperTrail: (you need to install it first) - # config.audit_with :paper_trail, '<%= @model_name.classify %>' - - # Display empty fields in show views: - # config.compact_show_view = false - - # Number of default rows per-page: - # config.default_items_per_page = 20 - - # Exclude specific models (keep the others): - # config.excluded_models = [<%= RailsAdmin::AbstractModel.all.map{|am| "'#{am.model}'" }.join(', ') %>] - - # Include specific models (exclude the others): - # config.included_models = [<%= RailsAdmin::AbstractModel.all.map{|am| "'#{am.model}'" }.join(', ') %>] - - # Label methods for model instances: - # config.label_methods << :description # Default is [:name, :title] - - - ################ Model configuration ################ - - # Each model configuration can alternatively: - # - stay here in a `config.model 'ModelName' do ... end` block - # - go in the model definition file in a `rails_admin do ... end` block - - # This is your choice to make: - # - This initializer is loaded once at startup (modifications will show up when restarting the application) but all RailsAdmin configuration would stay in one place. - # - Models are reloaded at each request in development mode (when modified), which may smooth your RailsAdmin development workflow. - - - # Now you probably need to tour the wiki a bit: https://github.com/sferik/rails_admin/wiki - # Anyway, here is how RailsAdmin saw your application's models when you ran the initializer: - -<% RailsAdmin::AbstractModel.all.map do |abstract_model| -%> - - - ### <%= abstract_model.model.model_name %> ### - - # config.model '<%= abstract_model.model.model_name %>' do - - # # You can copy this to a 'rails_admin do ... end' block inside your <%= abstract_model.model.model_name.to_s.underscore %>.rb model definition - - # # Found associations: - -<%= abstract_model.config.export.fields.select{|f| f.association?}.map do |field| -%{ # configure #{field.name.inspect}, #{field.type.inspect}#{" # Hidden" unless field.visible?} } -end.join("\n") %> - - # # Found columns: - -<%= abstract_model.config.export.fields.select{|f| !f.association?}.map do |field| -%{ # configure #{field.name.inspect}, #{field.type.inspect}#{" # Hidden" unless field.visible?} } -end.join("\n") %> - - # # Cross-section configuration: - - # # object_label_method :name # Name of the method called for pretty printing an *instance* of ModelName - # # label 'My model' # Name of ModelName (smartly defaults to ActiveRecord's I18n API) - # # label_plural 'My models' # Same, plural - # # weight 0 # Navigation priority. Bigger is higher. - # # parent OtherModel # Set parent model for navigation. MyModel will be nested below. OtherModel will be on first position of the dropdown - # # navigation_label # Sets dropdown entry's name in navigation. Only for parents! - - # # Section specific configuration: - - # list do - # # filters [:id, :name] # Array of field names which filters should be shown by default in the table header - # # items_per_page 100 # Override default_items_per_page - # # sort_by :id # Sort column (default is primary key) - # # sort_reverse true # Sort direction (default is true for primary key, last created first) - # end - # show do; end - # edit do; end - # export do; end - # # also see the create, update, modal and nested sections, which override edit in specific cases (resp. when creating, updating, modifying from another model in a popup modal or modifying from another model nested form) - # # you can override a cross-section field configuration in any section with the same syntax `configure :field_name do ... end` - # # using `field` instead of `configure` will exclude all other fields and force the ordering + ## == Devise == + # config.authenticate_with do + # warden.authenticate! scope: :user # end -<%- end -%> - + # config.current_user_method &:current_user + + ## == Cancan == + # config.authorize_with :cancan + + ## == PaperTrail == + # config.audit_with :paper_trail, 'User', 'PaperTrail::Version' # PaperTrail >= 3.0.0 + + ### More at https://github.com/sferik/rails_admin/wiki/Base-configuration + + config.actions do + dashboard # mandatory + index # mandatory + new + export + bulk_delete + show + edit + delete + show_in_app + + ## With an audit adapter, you can add: + # history_index + # history_show + end end diff --git a/lib/generators/rails_admin/templates/migration.rb b/lib/generators/rails_admin/templates/migration.rb deleted file mode 100644 index 3c743aa287..0000000000 --- a/lib/generators/rails_admin/templates/migration.rb +++ /dev/null @@ -1,18 +0,0 @@ -class CreateRailsAdminHistoriesTable < ActiveRecord::Migration - def self.up - create_table :rails_admin_histories do |t| - t.text :message # title, name, or object_id - t.string :username - t.integer :item - t.string :table - t.integer :month, :limit => 2 - t.integer :year, :limit => 5 - t.timestamps - end - add_index(:rails_admin_histories, [:item, :table, :month, :year], :name => 'index_rails_admin_histories' ) - end - - def self.down - drop_table :rails_admin_histories - end -end diff --git a/lib/generators/rails_admin/uninstall_generator.rb b/lib/generators/rails_admin/uninstall_generator.rb deleted file mode 100644 index 6de4c5842c..0000000000 --- a/lib/generators/rails_admin/uninstall_generator.rb +++ /dev/null @@ -1,22 +0,0 @@ -require 'rails/generators' -require File.expand_path('../utils', __FILE__) - -module RailsAdmin - class UninstallGenerator < Rails::Generators::Base - include Rails::Generators::Migration - include Generators::Utils::InstanceMethods - extend Generators::Utils::ClassMethods - source_root File.expand_path('../templates', __FILE__) - - desc "RailsAdmin uninstall" - - def uninstall - display "Why you leaving so soon? :(" - migration_template 'drop.rb', 'db/migrate/drop_rails_admin_histories_table.rb' - remove_file 'config/initializers/rails_admin.rb' - remove_file 'config/initializers/rails_admin.rb.example' - gsub_file "config/routes.rb", /mount RailsAdmin::Engine => \'\/.+\', :as => \'rails_admin\'/, '' - display "Done! Devise has been left untouched." - end - end -end diff --git a/lib/generators/rails_admin/utils.rb b/lib/generators/rails_admin/utils.rb index 107ad70589..ea19ff12ae 100644 --- a/lib/generators/rails_admin/utils.rb +++ b/lib/generators/rails_admin/utils.rb @@ -12,18 +12,6 @@ def ask_for(wording, default_value = nil, override_if_present_value = nil) ask(" ? #{wording} Press for [#{default_value}] >", :yellow).presence || default_value end end - - module ClassMethods - def next_migration_number(dirname) - if ActiveRecord::Base.timestamped_migrations - migration_number = Time.now.utc.strftime("%Y%m%d%H%M%S").to_i - migration_number += 1 - migration_number.to_s - else - "%.3d" % (current_migration_number(dirname) + 1) - end - end - end end end end