Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

0.3.4 stable #848

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
1 change: 1 addition & 0 deletions .gitignore
Expand Up @@ -33,3 +33,4 @@ test-rails*
public
.rvmrc
.rspec
.idea/**/*
30 changes: 30 additions & 0 deletions CHANGELOG.md
Expand Up @@ -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
Expand Down
12 changes: 9 additions & 3 deletions features/support/env.rb
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion lib/active_admin/application.rb
Expand Up @@ -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


Expand Down
46 changes: 40 additions & 6 deletions lib/active_admin/reloader.rb
@@ -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
Expand Down
12 changes: 6 additions & 6 deletions lib/active_admin/resource/action_items.rb
Expand Up @@ -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
Expand Down
2 changes: 1 addition & 1 deletion lib/active_admin/sass/css_loader.rb
Expand Up @@ -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

Expand Down
2 changes: 1 addition & 1 deletion lib/active_admin/version.rb
@@ -1,3 +1,3 @@
module ActiveAdmin
VERSION = '0.3.2'
VERSION = '0.3.4'
end
25 changes: 22 additions & 3 deletions lib/active_admin/views/index_as_table.rb
Expand Up @@ -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
Expand Down
68 changes: 60 additions & 8 deletions spec/unit/reloader_spec.rb
Expand Up @@ -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