module AutocompleteFor::ClassMethods
Public Instance Methods
autocomplete_for(association, field, options = {}, &block)
click to toggle source
# File lib/autocomplete_for/autocomplete_for.rb, line 9 def autocomplete_for(association, field, options = {}, &block) allow_nil = options[:allow_nil] || false validate :"validate_#{association}_by_#{field}" before_validation :"associate_#{association}_by_#{field}" instance_variable_set(:"@#{association}_#{field}_allow_nil", allow_nil) # method to set the name of the entity to autocomplete # def customer_name=(name) # @customer_name = name # end define_method(:"#{association}_#{field}=") do |name| instance_variable_set(:"@#{association}_#{field}", name) end # method to retrieve the name of the entity to autocomplete # def customer_name # self.customer_to.name : @customer_name # end define_method(:"#{association}_#{field}") do send(association.to_sym) ? send(association.to_sym).send(field.to_sym) : instance_variable_get(:"@#{association}_#{field}") end # Validation method to make sure the autocompleted name resolves to an actual entity # def validate_customer_by_name # return unless @customer_name # return if self.customer # return if @@customer_name_allow_nil && @customer_name == "" # # self.errors.add :customer_name, "#{@customer_name} does not exist" # end define_method(:"validate_#{association}_by_#{field}") do return unless instance_variable_get(:"@#{association}_#{field}") return if send(association.to_sym) return if self.class.instance_variable_get(:"@#{association}_#{field}_allow_nil") && instance_variable_get(:"@#{association}_#{field}") == "" errors.add(:"#{association}_#{field}", :does_not_exist) end # Resolve the autocompleted name to an actual entity # def autocomplete_find_customer_by_name # if self.site # self.customer = self.site.floor_locations.find(:first, :include => :location, :conditions => {:'locations.name' => @customer_name}) # end # end define_method(:"autocomplete_find_#{association}_by_#{field}", block) # def associate_customer_by_name # return unless @customer_name # # if @customer_name == '' # self.customer = nil # return # end # # autocomplete_find_customer_by_name # end define_method(:"associate_#{association}_by_#{field}") do return unless instance_variable_get(:"@#{association}_#{field}") if instance_variable_get(:"@#{association}_#{field}") == "" send(:"#{association}=", nil) return end send(:"autocomplete_find_#{association}_by_#{field}") end # set up validation on association in case the customer_name isn't set error_fields_name = :"@#{association}_autocomplete_error_fields" error_fields = instance_variable_get(error_fields_name) || [] error_fields << :"#{association}_#{field}" instance_variable_set(error_fields_name, error_fields) unless allow_nil # we must make sure that the validate_by_customer validation runs # after ALL validations on autocomplete fields # skip_callback :validate, :by, :"#{association}" validate :"validate_by_#{association}" unless instance_methods.include?("validate_by_#{association}") # def validate_by_customer # self.errors.add_on_blank(:customer) unless @@customer_autocomplete_error_fields.any? {|ef| self.errors[ef]} # end define_method(:"validate_by_#{association}") do return if self.class.instance_variable_get(error_fields_name).any? { |ef| errors[ef].any? } return unless send(:read_attribute_for_validation, association.to_sym).blank? errors.add(association.to_sym, :blank, options) end end end end