0.3.4 stable #848

Closed
wants to merge 7 commits into
from
View
@@ -33,3 +33,4 @@ test-rails*
public
.rvmrc
.rspec
+.idea/**/*
View
@@ -2,6 +2,36 @@
Nothing yet
+## 0.3.4
+
+2 commits by 2 authors
+
+### Bug Fixes
+
+* Fix reloading issues across operating systems.
+* Fix issue where SASS was recompiling on every request. This can seriously
+ decrease the load time of applications when running in development mode.
+ Thanks @dhiemstra for tracking this one down!
+
+### Contributors
+
+* Danny Hiemstra
+* Greg Bell
+
+## 0.3.3
+
+1 commit by 1 author
+
+### Enhancements
+
+* Only reload Active Admin when files in the load paths have changed. This is a
+ major speed increase in development mode. Also helps with memory consumption
+ because we aren't reloading Active admin all the time.
+
+### Contributors
+
+* Greg Bell
+
## 0.3.2
45 commits by 15 contributors
View
@@ -9,18 +9,24 @@
require File.expand_path('../../../spec/support/detect_rails_version', __FILE__)
ENV["RAILS"] = detect_rails_version
+ENV["RAILS_ENV"] ||= "cucumber"
+ENV['RAILS_ROOT'] = File.expand_path("../../../spec/rails/rails-#{ENV["RAILS"]}", __FILE__)
+
+
require 'rubygems'
require "bundler"
Bundler.setup
-ENV["RAILS_ENV"] ||= "cucumber"
-ENV['RAILS_ROOT'] = File.expand_path("../../../spec/rails/rails-#{ENV["RAILS"]}", __FILE__)
-
# Create the test app if it doesn't exists
unless File.exists?(ENV['RAILS_ROOT'])
system 'rake setup'
end
+# Ensure the Active Admin load path is happy
+require 'rails'
+require 'active_admin'
+ActiveAdmin.application.load_paths = [ENV['RAILS_ROOT'] + "/app/admin"]
+
require ENV['RAILS_ROOT'] + '/config/environment'
# Setup autoloading of ActiveAdmin and the load path
@@ -208,7 +208,7 @@ def remove_active_admin_load_paths_from_rails_autoload_and_eager_load
end
def attach_reloader
- ActiveAdmin::Reloader.new(Rails.version).attach!
+ ActiveAdmin::Reloader.new(Rails.application, self, Rails.version).attach!
end
@@ -1,23 +1,57 @@
module ActiveAdmin
+
+ class FileUpdateChecker < ::ActiveSupport::FileUpdateChecker
+
+ # Over-ride the default #updated_at to support the deletion of files
+ def updated_at
+ paths.map { |path| File.mtime(path) rescue Time.now }.max
+ end
+
+ end
+
# Deals with reloading Active Admin on each request in
# development and once in production.
class Reloader
- # @param [String] rails_version
- # The version of Rails we're using. We use this to switch between
- # the correcr Rails reloader class.
- def initialize(rails_version)
+ attr_reader :active_admin_app,
+ :rails_app,
+ :file_update_checker
+
+ # @param [ActiveAdmin::Application] app
+ # @param [String] rails_version The version of Rails we're using.
+ # We use this to switch between the correcrt Rails reloader class.
+ def initialize(rails_app, active_admin_app, rails_version)
+ @rails_app = rails_app
+ @active_admin_app = active_admin_app
@rails_version = rails_version.to_s
+ @file_update_checker = FileUpdateChecker.new(watched_paths) do
+ reload!
+ end
+ end
+
+ def reload!
+ active_admin_app.unload!
+ rails_app.reload_routes!
+ file_update_checker.paths.clear
+ watched_paths.each{|path| file_update_checker.paths << path }
end
# Attach to Rails and perform the reload on each request.
def attach!
+ # Bring the checker into local scope for the ruby block
+ checker = file_update_checker
+
reloader_class.to_prepare do
- ActiveAdmin.application.unload!
- Rails.application.reload_routes!
+ checker.execute_if_updated
end
end
+ def watched_paths
+ paths = active_admin_app.load_paths
+ active_admin_app.load_paths.each{|path| paths += Dir[File.join(path, "**", "*.rb")]}
+ paths
+ end
+
def reloader_class
if @rails_version[0..2] == '3.1'
ActionDispatch::Reloader
@@ -48,23 +48,23 @@ def clear_action_items!
def add_default_action_items
# New Link on all actions except :new and :show
add_action_item :except => [:new, :show] do
- if controller.action_methods.include?('new')
- link_to(I18n.t('active_admin.new_model', :model => active_admin_config.resource_name), new_resource_path)
+ if controller.action_methods.include?('new') && can?(:create, active_admin_config.resource_name.constantize)
+ link_to(I18n.t('active_admin.new_model', :model => active_admin_config.resource_name), new_resource_path, :class => "active_admin new_action")
end
end
# Edit link on show
add_action_item :only => :show do
- if controller.action_methods.include?('edit')
- link_to(I18n.t('active_admin.edit_model', :model => active_admin_config.resource_name), edit_resource_path(resource))
+ if controller.action_methods.include?('edit') && can?(:update, active_admin_config.resource_name.constantize)
+ link_to(I18n.t('active_admin.edit_model', :model => active_admin_config.resource_name), edit_resource_path(resource), :class => "active_admin edit_action")
end
end
# Destroy link on show
add_action_item :only => :show do
- if controller.action_methods.include?("destroy")
+ if controller.action_methods.include?("destroy") && can?(:destroy, active_admin_config.resource_name.constantize)
link_to(I18n.t('active_admin.delete_model', :model => active_admin_config.resource_name),
- resource_path(resource),
+ resource_path(resource), :class => "active_admin delete_action",
:method => :delete, :confirm => I18n.t('active_admin.delete_confirmation'))
end
end
@@ -9,7 +9,7 @@ class Sass::Importers::Filesystem
# We want to ensure that all *.css.scss files are loaded as scss files
def extensions_with_css
- extensions_without_css.merge('css.scss' => :scss)
+ extensions_without_css.merge('{css.,}scss' => :scss)
end
alias_method_chain :extensions, :css
@@ -1,3 +1,3 @@
module ActiveAdmin
- VERSION = '0.3.2'
+ VERSION = '0.3.4'
end
@@ -121,14 +121,33 @@ def id_column
end
# Adds links to View, Edit and Delete
+ #
+ # To include or exclude specific actions, use the :only and :except options.
+ # Insert additional markup before or after the default actions by using the :before and :after optinos. If the
+ # :before or :after options is a Proc, it will be called, with the current resource applied as first argument.
+ # Sample Usage: default_actions :except => [:delete, :edit]
def default_actions(options = {})
options = {
- :name => ""
+ :name => "",
+ :except => [],
+ :only => nil,
+ :before => "",
+ :after => ""
}.merge(options)
+
+ # :except takes precedence over :only.
+ display = options[:only] || [:view, :edit, :delete]
+ display.delete_if do |item| options[:except].include?(item) end
+
+ # puts controller.action_methods
+
column options[:name] do |resource|
links = link_to I18n.t('active_admin.view'), resource_path(resource), :class => "member_link view_link"
- links += link_to I18n.t('active_admin.edit'), edit_resource_path(resource), :class => "member_link edit_link"
- links += link_to I18n.t('active_admin.delete'), resource_path(resource), :method => :delete, :confirm => I18n.t('active_admin.delete_confirmation'), :class => "member_link delete_link"
+ links += options[:before].is_a?(Proc) ? options[:before].call(resource) : options[:before]
+ links += link_to I18n.t('active_admin.view'), resource_path(resource), :class => "member_link view_link" if display.include?(:view)
+ links += link_to I18n.t('active_admin.edit'), edit_resource_path(resource), :class => "member_link edit_link" if display.include?(:edit) && controller.action_methods.include?("edit")
+ links += link_to I18n.t('active_admin.delete'), resource_path(resource), :method => :delete, :confirm => I18n.t('active_admin.delete_confirmation'), :class => "member_link delete_link" if display.include?(:delete) && controller.action_methods.include?("destroy")
+ links += options[:after].is_a?(Proc) ? options[:after].call(resource) : options[:after]
links
end
end
View
@@ -4,25 +4,77 @@
begin
ActionDispatch::Reloader
rescue
- module ActionDispatch; module Reloader; end; end
+ module ActionDispatch; module Reloader; def self.to_prepare; end; end; end
end
begin
ActionDispatch::Callbacks
rescue
- module ActionDispatch; module Callbacks; end; end
+ module ActionDispatch; module Callbacks; def self.to_prepare; end; end; end
end
describe ActiveAdmin::Reloader do
- it "should use ActionDispatch::Reloader if rails 3.1" do
- reloader = ActiveAdmin::Reloader.new '3.1.0'
- reloader.reloader_class.should == ActionDispatch::Reloader
+ let(:rails_app){ mock(:reload_routes! => true)}
+ let(:mock_app){ mock(:load_paths => ["app/admin"], :unload! => true)}
+ let(:reloader){ ActiveAdmin::Reloader.new(rails_app, mock_app, "3.1.0")}
+
+ it "should initialize a new file update checker" do
+ ActiveSupport::FileUpdateChecker.should_receive(:new).with(mock_app.load_paths).and_return(mock(:execute_if_updated => true))
+ ActiveAdmin::Reloader.new(rails_app, mock_app, '3.1.0').attach!
+ end
+
+ describe "#reloader_class" do
+ it "should use ActionDispatch::Reloader if rails 3.1" do
+ reloader = ActiveAdmin::Reloader.new rails_app, mock_app, '3.1.0'
+ reloader.reloader_class.should == ActionDispatch::Reloader
+ end
+
+ it "should use ActionDispatch::Callbacks if rails 3.0" do
+ reloader = ActiveAdmin::Reloader.new rails_app, mock_app, '3.0.0'
+ reloader.reloader_class.should == ActionDispatch::Callbacks
+ end
+ end
+
+ describe "#reload!" do
+
+ it "should unload the active admin app" do
+ mock_app.should_receive(:unload!)
+ reloader.reload!
+ end
+
+ it "should reload the rails app routes" do
+ rails_app.should_receive(:reload_routes!)
+ reloader.reload!
+ end
+
+ it 'should reset the files within the file_update_checker' do
+ reloader.file_update_checker.paths.should_receive(:clear)
+ reloader.file_update_checker.paths.should_receive(:<<).with("app/admin")
+ reloader.reload!
+ end
+
end
- it "should use ActionDispatch::Callbacks if rails 3.0" do
- reloader = ActiveAdmin::Reloader.new '3.0.0'
- reloader.reloader_class.should == ActionDispatch::Callbacks
+ describe "#watched_paths" do
+ let(:mock_app){ ActiveAdmin::Application.new }
+ let(:admin_path){ File.join(Rails.root, "app", "admin") }
+
+ before do
+ mock_app.load_paths = [admin_path]
+ end
+
+ it "should return the load path directories" do
+ reloader.watched_paths.should include(admin_path)
+ end
+
+ it "should include all files in the directory" do
+ root = Rails.root + "/app/admin"
+ reloader.watched_paths.should include(*Dir["#{admin_path}/**/*.rb"])
+ end
+
end
+
+
end