module ActiveScaffold::Finder
Constants
- NullComparators
- NumericComparators
- StringComparators
Attributes
Public Class Methods
# File lib/active_scaffold/finder.rb, line 9 def self.like_operator @@like_operator ||= ::ActiveRecord::Base.connection.adapter_name == "PostgreSQL" ? "ILIKE" : "LIKE" end
Protected Instance Methods
# File lib/active_scaffold/finder.rb, line 227 def active_scaffold_conditions @active_scaffold_conditions ||= [] end
# File lib/active_scaffold/finder.rb, line 237 def active_scaffold_habtm_joins @active_scaffold_habtm_joins ||= [] end
# File lib/active_scaffold/finder.rb, line 232 def active_scaffold_includes @active_scaffold_includes ||= [] end
if someone excludes association from includes in configuration and sorts by that that column… database will not be happy about it :-) just a safety check to prevent many many database queries
# File lib/active_scaffold/finder.rb, line 300 def add_association_to_includes_for_sorting(sorting, full_includes) if sorting && sorting.sorts_by_method? sorting_column = sorting.first.first #wants to sort by assocation which is not included bad performance... if sorting_column.association && !sorting_column.polymorphic_association? && sorting_column.includes.empty? && !full_includes.include?(sorting_column.association.name) full_includes << sorting_column.association.name end end full_includes end
# File lib/active_scaffold/finder.rb, line 241 def all_conditions merge_conditions( active_scaffold_conditions, # from the search modules conditions_for_collection, # from the dev conditions_from_params, # from the parameters (e.g. /users/list?first_name=Fred) conditions_from_constraints, # from any constraints (embedded scaffolds) active_scaffold_session_storage[:conditions] # embedding conditions (weaker constraints) ) end
# File lib/active_scaffold/finder.rb, line 312 def append_to_query(query, options) options.assert_valid_keys :where, :select, :group, :reorder, :limit, :offset, :joins, :includes, :lock, :readonly, :from options.reject{|k, v| v.blank?}.inject(query) do |query, (k, v)| query.send((k.to_sym), v) end end
returns a single record (the given id) but only if it's allowed for the specified action. accomplishes this by checking model.#{action}_authorized? TODO: this should reside on the model, not the controller
# File lib/active_scaffold/finder.rb, line 254 def find_if_allowed(id, crud_type, klass = beginning_of_chain) record = klass.find(id) raise ActiveScaffold::RecordNotAllowed, "#{klass} with id = #{id}" unless record.authorized_for?(:crud_type => crud_type.to_sym) return record end
returns a Paginator::Page
(not from ActiveRecord::Paginator) for the given parameters options may include:
-
:sorting - a Sorting DataStructure (basically an array of hashes of field => direction, e.g. [{:field1 => 'asc'}, {:field2 => 'desc'}]). please note that multi-column sorting has some limitations: if any column in a multi-field sort uses method-based sorting, it will be ignored. method sorting only works for single-column sorting.
-
:per_page
-
:page
TODO: this should reside on the model, not the controller
# File lib/active_scaffold/finder.rb, line 266 def find_page(options = {}) options.assert_valid_keys :sorting, :per_page, :page, :count_includes, :pagination search_conditions = all_conditions full_includes = (active_scaffold_includes.blank? ? nil : active_scaffold_includes) options[:per_page] ||= 999999999 options[:page] ||= 1 #TODO not supported by kaminary options[:count_includes] ||= full_includes unless search_conditions.nil? klass = beginning_of_chain klass = klass.where("") if klass.is_a?(Array) # create a general-use options array that's compatible with Rails finders finder_options = { :reorder => options[:sorting].try(:clause), :where => search_conditions, :joins => joins_for_finder, :includes => add_association_to_includes_for_sorting(options[:sorting], full_includes)} finder_options.merge! custom_finder_options # we build the paginator differently for method- and sql-based sorting records = if options[:sorting] && options[:sorting].sorts_by_method? Kaminari.paginate_array(sort_collection_by_column(append_to_query(klass, finder_options).to_a, *options[:sorting].first)) else append_to_query(klass, finder_options) end records = records.page(options[:page]).per(options[:per_page]) if options[:pagination] records end
# File lib/active_scaffold/finder.rb, line 319 def joins_for_finder case joins_for_collection when String [ joins_for_collection ] when Array joins_for_collection else [] end + active_scaffold_habtm_joins end
# File lib/active_scaffold/finder.rb, line 330 def merge_conditions(*conditions) segments = [] conditions.each do |condition| unless condition.blank? sql = active_scaffold_config.model.send(:sanitize_sql, condition) segments << sql unless sql.blank? end end "(#{segments.join(') AND (')})" unless segments.empty? end
TODO: this should reside on the column, not the controller
# File lib/active_scaffold/finder.rb, line 342 def sort_collection_by_column(collection, column, order) sorter = column.sort[:method] collection = collection.sort_by { |record| value = (sorter.is_a? Proc) ? record.instance_eval(&sorter) : record.instance_eval(sorter) value = '' if value.nil? value } collection.reverse! if order.downcase == 'desc' collection end