lib/netzke/data_accessor.rb in netzke-basepack-0.5.14 vs lib/netzke/data_accessor.rb in netzke-basepack-0.6.0

- old
+ new

@@ -1,74 +1,102 @@ -require "netzke/active_record/data_accessor" -require "searchlogic" +require 'netzke/active_record' module Netzke - # This module is included into such data-driven widgets as GridPanel, FormPanel, etc. + # This module is included into such data-driven components as GridPanel, FormPanel, etc. module DataAccessor - # This method should be called from the constructor of the widget. - def apply_helpers - # Generic extensions to the data model - if data_class # because some widgets, like FormPanel, may have it optional - data_class.send(:include, Netzke::ActiveRecord::DataAccessor) if !data_class.include?(Netzke::ActiveRecord::DataAccessor) - end - end # Returns options for comboboxes in grids/forms def combobox_options_for_column(column, method_options = {}) + query = method_options[:query] + # First, check if we have options for this column defined in persistent storage options = column[:combobox_options] && column[:combobox_options].split("\n") if options - (method_options[:query].nil? ? options : options.select{ |o| o.index(/^#{method_options[:query]}/) }).map{ |el| [el] } + query ? options.select{ |o| o.index(/^#{query}/) }.map{ |el| [el] } : options else assoc, assoc_method = assoc_and_assoc_method_for_column(column) if assoc # Options for an asssociation attribute + + relation = assoc.klass.where({}) + + relation = relation.extend_with(method_options[:scope]) if method_options[:scope] - search = assoc.klass.searchlogic - - # apply scopes - method_options[:scopes] && method_options[:scopes].each do |s| - if s.is_a?(Array) - scope_name, *args = s - search.send(scope_name, *args) - else - search.send(s, true) - end - end - if assoc.klass.column_names.include?(assoc_method) # apply query - search.send("#{assoc_method}_like", "#{method_options[:query]}%") if method_options[:query] - search.all.map{ |r| [r.send(assoc_method)] } + relation = relation.where(:"#{assoc_method}".like => "#{query}%") if query.present? + relation.all.map{ |r| [r.send(assoc_method)] } else - search.all.map{ |r| r.send(assoc_method) }.select{ |value| value =~ /^#{method_options[:query]}/ }.map{ |v| [v] } + relation.all.map{ |r| r.send(assoc_method) }.select{ |value| value =~ /^#{query}/ }.map{ |v| [v] } end else # Options for a non-association attribute - data_class.options_for(column[:name], method_options[:query]).map{|s| [s]} + res=data_class.netzke_combo_options_for(column[:name], method_options) + + # ensure it is an array-in-array, as Ext will fail otherwise + raise RuntimeError, "netzke_combo_options_for should return an Array" unless res.kind_of? Array + return [[]] if res.empty? + + unless res.first.kind_of? Array + res=res.map do |v| + [v] + end + end + return res + + end end end + # Normalize array of attributes # [:col1, "col2", {:name => :col3}] => # [{:name => "col1"}, {:name => "col2"}, {:name => "col3"}] - def normalize_attr_config(cols) - cols.map do |c| - c.is_a?(Symbol) || c.is_a?(String) ? {:name => c.to_s} : c.merge(:name => c[:name].to_s) - end + def normalize_attrs(attrs) + attrs.map{ |a| normalize_attr(a) } end + # Normalize an attribute, e.g.: + # :first_name => + # {:name => "first_name"} + def normalize_attr(a) + a.is_a?(Symbol) || a.is_a?(String) ? {:name => a.to_s} : a.merge(:name => a[:name].to_s) + end + # Returns association and association method for a column def assoc_and_assoc_method_for_column(c) assoc_name, assoc_method = c[:name].split('__') assoc = data_class.reflect_on_association(assoc_name.to_sym) if assoc_method [assoc, assoc_method] end def association_attr?(name) !!name.to_s.index("__") end - + + # Model class + # (We can't memoize this method because at some point we extend it, e.g. in Netzke::DataAccessor) + def data_class + @data_class ||= begin + klass = "Netzke::ModelExtensions::#{config[:model]}For#{short_component_class_name}".constantize rescue nil + klass || original_data_class + end + end + + # Model class before model extensions are taken into account + def original_data_class + @original_data_class ||= begin + ::ActiveSupport::Deprecation.warn("data_class_name option is deprecated. Use model instead", caller) if config[:data_class_name] + model_name = config[:model] || config[:data_class_name] + model_name.nil? ? raise(ArgumentError, "No model specified for component #{global_id}") : model_name.constantize + end + end + + # whether a column is bound to the primary_key + def primary_key_attr?(a) + data_class && a[:name].to_s == data_class.primary_key + end + end end \ No newline at end of file