module AnafHabtm module ActiveRecord def autocomplete_format(&block) class_eval do @autocomplete_block = block def self.to_autocomplete(items) items.map{|t| @autocomplete_block.call(t)}.to_json end end end # Needs to call scopes on a class and pass it values that are # pulled from a hash called obj_attr def make_scope_string(find_opts) _scopes = [] find_opts.each{ |scope, attr_name| if attr_name.class == Hash _scopes << "#{scope.to_s}(obj_attr[#{name.first[0].to_s}][#{name.first[1].to_s}])" else _scopes << "#{scope.to_s}(obj_attr[#{name.to_s}])" end } _scopes.join(".") end def anaf_habtm(association, options={}) ar_opts = options[:ar_options] ||= {} klass = ar_opts[:class_name] ||= association.to_s.singularize.camelize class_eval do has_and_belongs_to_many association.to_sym, ar_opts end find_line = "obj = obj ||= #{klass}.#{make_scope_string(options[:find])}.first" if options.has_key?(:find) association = association.to_s.underscore.tableize scope_string = class_eval <name} params[opts[:commentary]] = commentary if opts.has_key?(:commentary) obj = obj ||= klass.new obj = klass.find(obj) unless obj.new_record? obj.decoration = a if a obj.attributes = params obj.save obj end self.send("#{association.to_s}=", coll) } define_method "#{association.to_s}_text", lambda{ StringReader.new.write_items(self.send(association.to_s)) do |item| name = item.send(opts[:name]) name = item.decorate(name) if item.methods.include?("decorate") [name, opts.has_key?(:commentary) ? item.send(opts[:commentary]) : ""] end } end end def named_association(member, attribute, opts={}) member = member.to_s klass = (opts.has_key?(:class_name) ? opts[:class_name] : member.to_s.singularize.camelize).constantize attribute = attribute.to_s if opts.has_key?(:create) class_eval do define_method "#{member}_#{attribute}=", lambda{|value| return if value.blank? obj = klass.named(value) obj = obj ||= klass.create(attribute => value) self.send("#{member}=", obj) } end else class_eval do define_method "#{member}_#{attribute}=", lambda{|value| self.send("#{member}=",klass.named(value)) unless value.blank? } end end class_eval "def #{member}_#{attribute}; #{member}.#{attribute} if #{member}; end;" end def search_on(*cols) class_eval "def self.search_columns; #{cols.map{|t| t.to_s}.to_ary.inspect}; end;" class_eval do scope :search, lambda{|str| items = like_condition(str.downcase) if scopes.has_key?(:search_mod) items = items.search_mod end items } scope :with_name, lambda{|str| equals_condition(str.downcase).limit(1) } end end def lookup(params) str = params[:id] if str.match(/\D/) named(str) else find(str) end end def like_condition(str) where(condition("ilike '%#{str}%'")) end def equals_condition(str) where(condition("= '#{str.downcase}'")) end def named(str) with_name(str).first end def condition(cond) search_columns.map{|c| "trim(lower(#{c})) #{cond}"}.join(" or ") end end end