class Lolita::Configuration::Field::Array

Fields with Array is used to

Polymorphic builder (:polymorphic)

Create two select boxes one of all related classes and second with related records for that class. Related classes can have polymorphic_select_name instance method, that is used to populate second select with visible values by default it calles text_method. It will fallback first content column. Class should respond to one of these.

Constants

MAX_RECORD_COUNT

Public Class Methods

new(dbi,name,*args, &block) click to toggle source
Calls superclass method Lolita::Configuration::Field::Base::new
# File lib/lolita/configuration/field/array.rb, line 22
def initialize dbi,name,*args, &block
  @include_blank=true
  super
  self.find_dbi_field unless self.dbi_field

  @association ||= self.dbi_field ? self.dbi_field.association : detect_association
  self.run(:after_association_loaded)
  self.builder = detect_builder unless @builder
  self.name = recognize_real_name
end

Public Instance Methods

association_values(record = nil) click to toggle source

Collect values for array type field. Uses text_method for content. By default it search for first String type field in DB. Uses value_method for value, by default it it is id.

# File lib/lolita/configuration/field/array.rb, line 61
def association_values(record = nil) #TODO test
  @association_values=if values
    values
  elsif search
    search.run("")
  elsif @association && @association.polymorphic?
    polymorphic_association_values(record)
  elsif @association
    klass=@association.klass
    options_array(collect_records_for(klass))
  else
    []
  end
  @association_values
end
current_text_method(klass) click to toggle source
# File lib/lolita/configuration/field/array.rb, line 97
def current_text_method(klass)
  @text_method || default_text_method(klass)
end
current_value_method() click to toggle source
# File lib/lolita/configuration/field/array.rb, line 101
def current_value_method
  @value_method || :id
end
detect_association() click to toggle source
# File lib/lolita/configuration/field/array.rb, line 130
def detect_association
  unless @association
    dbi.associations[self.name.to_s]
  else
    @association
  end
end
detect_builder() click to toggle source
# File lib/lolita/configuration/field/array.rb, line 116
def detect_builder
  if @association
    if @association.polymorphic?
      "polymorphic"
    elsif @association.macro == :many_to_many
      "autocomplete"
    else
      "select"
    end
  else
    "select"
  end
end
options_array(collection) click to toggle source
# File lib/lolita/configuration/field/array.rb, line 90
def options_array(collection)
  klass = collection.last ? collection.last.class : nil
  collection.map{|r|
    [r.send(current_text_method(klass)),r.send(current_value_method)]
  }
end
polymorphic_association_values(options={}) click to toggle source

Collect values for polymorphic association, you may pass

  • :klass - class that's records are used

  • :record - record class that has polymorphic association. It is used to call to detect related object class.

# File lib/lolita/configuration/field/array.rb, line 80
def polymorphic_association_values(options={})
  options ||= {}
  options[:klass] ||= options[:record] && options[:record].send(self.name) ? options[:record].send(self.name).class : nil
  if options[:klass]
    options_array(collect_records_for(options[:klass]))
  else
    []
  end
end
polymorphic_classes() click to toggle source
# File lib/lolita/configuration/field/array.rb, line 138
def polymorphic_classes
  if @related_classes
    @related_classes.map do |klass|
      [klass.constantize.lolita_model_name.human, klass.to_s]
    end
  else
    []
  end
end
recognize_real_name() click to toggle source
# File lib/lolita/configuration/field/array.rb, line 148
def recognize_real_name
  if @association && !@association.polymorphic? && @association.macro == :one
    @real_name = self.name
    self.name = @association.key
  else
    @name
  end
end
values(value=nil, &block) click to toggle source

Use this with block if values are dynamicly collected.

# File lib/lolita/configuration/field/array.rb, line 52
def values value=nil, &block
  @values=value || block if value || block_given?
  @values
end
values=(value=nil) click to toggle source
# File lib/lolita/configuration/field/array.rb, line 47
def values=(value=nil)
  @values=value
end
view_values(view) click to toggle source

used in views for shorter accessing to values

# File lib/lolita/configuration/field/array.rb, line 106
def view_values(view)
  record = view.send(:current_form).object
  values = association_values(record)
  if values.respond_to?(:call)
    values.call(view)
  else
    association_values(record)
  end
end

Private Instance Methods

collect_records_for(klass) click to toggle source
# File lib/lolita/configuration/field/array.rb, line 178
def collect_records_for(klass)
  if klass.count > MAX_RECORD_COUNT
    raise ArgumentError.new("#{@dbi.klass} field #{@name} association has too many records(#{klass.count})")
  else
    klass.all
  end
end
default_text_method(klass) click to toggle source
# File lib/lolita/configuration/field/array.rb, line 159
def default_text_method(klass)
  assoc_dbi=Lolita::DBI::Base.create(klass) rescue nil
  if assoc_dbi
    field = assoc_dbi.fields.detect{|f| f.name.to_s == "title"}
    field ||= assoc_dbi.fields.detect{|f| f.name.to_s == "name"}
    field ||= assoc_dbi.fields.detect{|f| f.type.to_s=="string"}
    if field
      field.name
    else
      raise Lolita::FieldTypeError, %^
      Can't find any content field in #{assoc_dbi.klass}.
      Use text_method in #{klass} to set one.
      ^
    end
  else
    warn("Not a ORM class (#{klass.inspect})")
  end
end