lib/admin_assistant.rb in admin_assistant-1.0.0 vs lib/admin_assistant.rb in admin_assistant-1.0.1
- old
+ new
@@ -8,35 +8,44 @@
end
end
require 'will_paginate'
class AdminAssistant
- attr_reader :base_settings, :controller_class, :form_settings,
- :index_settings, :model_class, :show_settings
- attr_accessor :actions, :custom_destroy
- attr_writer :model_class_name
+ cattr_accessor :request_start_time
+ def self.profile(msg)
+ if self.request_start_time
+ Rails.logger.info "#{msg}: #{Time.now - self.request_start_time}"
+ end
+ end
+
def self.template_file(template_name)
"#{File.dirname(__FILE__)}/views/#{template_name}.html.erb"
end
+ attr_reader :base_settings, :controller_class, :form_settings,
+ :index_settings, :model_class, :show_settings
+ attr_accessor :actions, :custom_destroy, :default_search_matches_on
+ attr_writer :model_class_name
+
def initialize(controller_class, model_class)
@controller_class, @model_class = controller_class, model_class
@model = Model.new model_class
@actions = [:index, :create, :update, :show]
@form_settings = FormSettings.new self
@index_settings = IndexSettings.new self
@show_settings = ShowSettings.new self
@base_settings = BaseSettings.new self
+ @default_search_matches_on = @model.searchable_columns.map &:name
end
def [](name)
@base_settings[name]
end
def accumulate_columns(names)
- columns = paperclip_attachments.map { |paperclip_attachment|
+ columns = @model.paperclip_attachments.map { |paperclip_attachment|
PaperclipColumn.new paperclip_attachment
}
names.each do |column_name|
unless columns.any? { |column| column.contains?(column_name) }
column = column column_name
@@ -49,38 +58,48 @@
def accumulate_belongs_to_columns(names)
accumulate_columns(names).select { |column| column.is_a?(BelongsToColumn) }
end
def autocomplete_actions
- ac_actions = []
- if [:new, :create, :edit, :update].any? { |action|
- actions.include?(action)
- }
- accumulate_belongs_to_columns(default_column_names).each { |column|
- ac_actions << "autocomplete_#{column.name}".to_sym
+ @autocomplete_actions ||= begin
+ ac_actions = []
+ if [:new, :create, :edit, :update].any? { |action|
+ actions.include?(action)
}
- end
- if actions.include?(:index)
- base_settings.all_polymorphic_types.each do |p_type|
- ac_actions << "autocomplete_#{p_type.name.underscore.downcase}".to_sym
+ defaults = @model.default_column_names
+ accumulate_belongs_to_columns(defaults).each { |column|
+ ac_actions << "autocomplete_#{column.name}".to_sym
+ }
end
+ if actions.include?(:index)
+ base_settings.all_polymorphic_types.each do |p_type|
+ ac_actions << "autocomplete_#{p_type.name.underscore.downcase}".to_sym
+ end
+ end
+ ac_actions.uniq
end
- ac_actions.uniq
+ @autocomplete_actions
end
def column(name)
- if file_columns.include?(name.to_s)
+ if @model.file_columns.include?(name.to_s)
FileColumnColumn.new name
- elsif paperclip_attachments.include?(name)
+ elsif @model.paperclip_attachments.include?(name)
PaperclipColumn.new name
- elsif (belongs_to_assoc = belongs_to_assoc(name) or
- belongs_to_assoc = belongs_to_assoc_by_foreign_key(name))
+ elsif (belongs_to_assoc = @model.belongs_to_assoc(name) or
+ belongs_to_assoc = @model.belongs_to_assoc_by_foreign_key(name))
column_based_on_belongs_to_assoc name, belongs_to_assoc
- elsif belongs_to_assoc = belongs_to_assoc_by_polymorphic_type(name)
+ elsif belongs_to_assoc = @model.belongs_to_assoc_by_polymorphic_type(name)
# skip it, actually
elsif (ar_column = @model_class.columns_hash[name.to_s])
ActiveRecordColumn.new ar_column
+ elsif has_many_assoc = @model.has_many_assoc(name)
+ HasManyColumn.new(
+ has_many_assoc,
+ :match_text_fields_in_search =>
+ search_settings[name].match_text_fields_for_association?
+ )
else
VirtualColumn.new name, @model_class, self
end
end
@@ -107,56 +126,57 @@
def controller_css_class(controller)
controller.controller_path.gsub(%r|/|, '_')
end
- def dispatch_to_request_method(request_class, controller)
- controller.instance_variable_set :@admin_assistant, self
- @request = request_class.new(self, controller)
- @request.call
- @request = nil
+ def crudful_request_methods
+ [:create, :destroy, :edit, :index, :new, :update, :show]
end
+ def default_column_names
+ @model.default_column_names
+ end
+
+ def file_columns
+ @model.file_columns
+ end
+
def method_missing(meth, *args)
- if @model.respond_to?(meth)
- @model.send meth, *args
+ if crudful_request_methods.include?(meth) and args.size == 1
+ self.class.request_start_time = Time.now if ENV['PROFILE_LOGGING']
+ Request.dispatch meth, self, args.first
+ elsif autocomplete_actions && autocomplete_actions.include?(meth)
+ Request.dispatch :autocomplete, self, args.first
+ elsif meth.to_s =~ /(.*)\?/ && crudful_request_methods.include?($1.to_sym)
+ supports_action? $1
else
- request_methods = [
- :create, :destroy, :edit, :index, :new, :update, :show
- ]
- if request_methods.include?(meth) and args.size == 1
- request_class = Request.const_get meth.to_s.capitalize
- dispatch_to_request_method request_class, args.first
- elsif autocomplete_actions && autocomplete_actions.include?(meth)
- dispatch_to_request_method Request::Autocomplete, args.first
- else
- if meth.to_s =~ /(.*)\?/ && request_methods.include?($1.to_sym)
- @controller_class.public_instance_methods.include?($1)
- elsif @request.respond_to?(meth)
- @request.send meth, *args
- else
- super
- end
- end
+ super
end
end
def model_class_name
@model_class_name ||
@model_class.name.gsub(/([A-Z])/, ' \1')[1..-1].downcase
end
- def profile(msg)
- if @request_start_time
- puts "#{msg}: #{Time.now - @request_start_time}"
- end
+ def paperclip_attachments
+ @model.paperclip_attachments
end
def search_settings
@index_settings.search_settings
end
+ def supports_action?(action)
+ @memoized_action_booleans ||= {}
+ unless @memoized_action_booleans.has_key?(action)
+ @memoized_action_booleans[action] =
+ @controller_class.public_instance_methods.include?(action)
+ end
+ @memoized_action_booleans[action]
+ end
+
def url_params(a = action)
{:controller => @controller_class.controller_path, :action => a}
end
module ControllerMethods
@@ -166,28 +186,39 @@
end
end
module ControllerClassMethods
def admin_assistant_for(model_class, &block)
- self.admin_assistant = AdminAssistant.new(self, model_class)
- builder = Builder.new self.admin_assistant
- if block
- block.call builder
- end
- self.helper AdminAssistant::Helper
- self.admin_assistant.controller_actions.each do |action|
- self.send(:define_method, action) do
- self.class.admin_assistant.send(action, self)
+ begin
+ self.admin_assistant = AdminAssistant.new(self, model_class)
+ builder = Builder.new self.admin_assistant
+ if block
+ block.call builder
end
+ self.helper AdminAssistant::Helper
+ self.admin_assistant.controller_actions.each do |action|
+ self.send(:define_method, action) do
+ self.class.admin_assistant.send(action, self)
+ end
+ end
+ rescue ActiveRecord::StatementInvalid
+ Rails.logger.info "Skipping admin_assistant_for for #{self.name} because the table doesn't exist in the DB. Hopefully that's because you're deploying with a migration."
end
end
end
class Model
def initialize(ar_model)
@ar_model = ar_model
end
+
+ def accessors
+ @ar_model.instance_methods.
+ select { |m| m =~ /=$/ }.
+ map { |m| m.gsub(/=/, '')}.
+ select { |m| @ar_model.instance_methods.include?(m) }
+ end
def belongs_to_associations
@ar_model.reflect_on_all_associations.select { |assoc|
assoc.macro == :belongs_to
}
@@ -221,30 +252,29 @@
def file_columns
unless @file_columns
@file_columns = []
if @ar_model.respond_to?(:file_column)
- names_to_check = @ar_model.columns.map &:name
- names_to_check.concat(
- @ar_model.instance_methods.
- select { |m| m =~ /=$/ }.
- map { |m| m.gsub(/=/, '')}.
- select { |m| @ar_model.instance_methods.include?(m) }
- )
- names_to_check.uniq.each do |name|
- suffixes = %w( relative_path dir relative_dir temp )
- if suffixes.all? { |suffix|
+ names_to_check = @ar_model.columns.map(&:name).concat(accessors).uniq
+ @file_columns = names_to_check.select { |name|
+ %w( relative_path dir relative_dir temp ).all? { |suffix|
@ar_model.method_defined? "#{name}_#{suffix}".to_sym
}
- @file_columns << name
- end
- end
+ }
end
end
@file_columns
end
+ def has_many_assoc(association_name)
+ @ar_model.reflect_on_all_associations.select { |assoc|
+ assoc.macro == :has_many
+ }.detect { |assoc|
+ assoc.name.to_s == association_name.to_s
+ }
+ end
+
def paperclip_attachments
pa = []
if @ar_model.respond_to?(:attachment_definitions)
if @ar_model.attachment_definitions
pa = @ar_model.attachment_definitions.map { |name, definition|
@@ -263,15 +293,5 @@
end
end
ActionController::Base.send :include, AdminAssistant::ControllerMethods
-css_dir = "#{RAILS_ROOT}/public/stylesheets/admin_assistant"
-FileUtils.mkdir(css_dir) unless File.exist?(css_dir)
-FileUtils.cp_r(Dir.glob("#{File.dirname(__FILE__)}/stylesheets/*"), css_dir)
-FileUtils.copy(
- "#{File.dirname(__FILE__)}/javascripts/admin_assistant.js",
- "#{RAILS_ROOT}/public/javascripts/admin_assistant.js"
-)
-images_dir = "#{RAILS_ROOT}/public/images/admin_assistant"
-FileUtils.mkdir(images_dir) unless File.exist?(images_dir)
-FileUtils.cp_r(Dir.glob("#{File.dirname(__FILE__)}/images/*"), images_dir)