class Lolita::Configuration::Field::Array
-
create select for belongs_to association or
-
has_and_belongs_to_many field for selecting all associated objects or
-
for polymorphic belongs_to associations
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
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
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
# File lib/lolita/configuration/field/array.rb, line 43 def create_search *args, &block Lolita::Configuration::Search.new(Lolita::DBI::Base.create(@association.klass),*args,&block) end
# File lib/lolita/configuration/field/array.rb, line 97 def current_text_method(klass) @text_method || default_text_method(klass) end
# File lib/lolita/configuration/field/array.rb, line 101 def current_value_method @value_method || :id end
# File lib/lolita/configuration/field/array.rb, line 130 def detect_association unless @association dbi.associations[self.name.to_s] else @association end end
# 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
# 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
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
# 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
# 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
For details see Lolita::Configuration::Search
# File lib/lolita/configuration/field/array.rb, line 34 def search *args, &block if (args && args.any?) || block_given? self.after_association_loaded do @search = create_search(*args,&block) end end @search end
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
# File lib/lolita/configuration/field/array.rb, line 47 def values=(value=nil) @values=value end
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
# 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
# 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