app/models/msip/modelo.rb in msip-2.2.0.alfa3 vs app/models/msip/modelo.rb in msip-2.2.0.beta1

- old
+ new

@@ -1,99 +1,103 @@ +# frozen_string_literal: true module Msip module Modelo extend ActiveSupport::Concern include Msip::Localizacion # En principio un modelo tiene una id - - included do - # Si atr corresponde a tabla combinada (con relación has_many) o a + included do + # Si atr corresponde a tabla combinada (con relación has_many) o a # tabla con accepts_nested_attributes_for la retorna. # En otro caso retorna nil def self.asociacion_combinada(atr) r = nil - if atr.is_a?(Hash) && - (atr.first[0].to_s.ends_with?('_ids') || - atr.first[0].to_s.ends_with?('_attributes')) - na = atr.first[0].to_s.chomp('_ids') + if atr.is_a?(Hash) && + (atr.first[0].to_s.ends_with?("_ids") || + atr.first[0].to_s.ends_with?("_attributes")) + na = atr.first[0].to_s.chomp("_ids") na = na.chomp("_attributes") - a = self.reflect_on_all_associations - r = a.select { |ua| ua.name.to_s == na }[0] + a = reflect_on_all_associations + r = a.select { |ua| ua.name.to_s == na }[0] if r.nil? - msg="Aunque #{atr} es como nombre de asociación combinada, " + - "no se encontró #{na} entre las de #{self.to_s}" - puts msg + msg = "Aunque #{atr} es como nombre de asociación combinada, " \ + "no se encontró #{na} entre las de #{self}" + Rails.logger.debug(msg) raise msg end else - na = atr.to_s.chomp('_ids') - na = na.chomp('_attributes') - a = self.reflect_on_all_associations - p = a.select { |ua| ua.name.to_s == na && - (ua.macro == :has_many || - ua.macro == :has_and_belongs_to_many) } - if p.count>0 - r=p[0] + na = atr.to_s.chomp("_ids") + na = na.chomp("_attributes") + a = reflect_on_all_associations + p = a.select do |ua| + ua.name.to_s == na && + (ua.macro == :has_many || + ua.macro == :has_and_belongs_to_many) end + if p.count > 0 + r = p[0] + end end - return r + r end # Si atr es llave foranea retorna asociación a este modelo # en otro caso retorna nil def self.asociacion_llave_foranea(atr) - aso = self.reflect_on_all_associations - bel = aso.select { |a| a.macro == :belongs_to } + aso = reflect_on_all_associations + bel = aso.select { |a| a.macro == :belongs_to } fk = bel.map do |e| e.foreign_key.to_s end - if fk.include? atr.to_s - r = aso.select { |a| + if fk.include?(atr.to_s) + r = aso.select do |a| (a.is_a?(ActiveRecord::Reflection::HasManyReflection) || - a.is_a?(ActiveRecord::Reflection::BelongsToReflection)) && - a.foreign_key.to_s == atr.to_s - }[0] + a.is_a?(ActiveRecord::Reflection::BelongsToReflection)) && + a.foreign_key.to_s == atr.to_s + end[0] return r end ln = bel.map do |e| e.name.to_s end - if ln.include? atr.to_s - r = aso.select { |a| + if ln.include?(atr.to_s) + r = aso.select do |a| (a.is_a?(ActiveRecord::Reflection::HasManyReflection) || - a.is_a?(ActiveRecord::Reflection::BelongsToReflection)) && - a.name.to_s == atr.to_s - }[0] + a.is_a?(ActiveRecord::Reflection::BelongsToReflection)) && + a.name.to_s == atr.to_s + end[0] return r end - return nil + nil end # Si atr es atributo que es llave foranea retorna su clase # si no retorna nil def self.clase_llave_foranea(atr) - r = self.asociacion_llave_foranea(atr) + r = asociacion_llave_foranea(atr) if r return r.class_name.constantize end - return nil + + nil end attr_accessor :creado_en + def creado_en created_at end attr_accessor :actualizado_en + def actualizado_en updated_at end - # Como presentar un registro por ejemplo en un campo de selección # Si se sobrecarga, sobrecargar también orden_presenta_nombre def presenta_nombre if respond_to?(:nombre) self[:nombre] @@ -104,76 +108,80 @@ # Columnas por las cuales ordenar en campos de selección # para que resulten ordenados según presenta_nombre # Debe coincidir con presenta_nombre def self.orden_presenta_nombre - if self.columns && self.columns.map(&:name).include?('nombre') - ['lower(nombre)'] + if columns&.map(&:name)&.include?("nombre") + ["lower(nombre)"] else [:id] end end # Presentar campo atr del registro en index y show genérico (no sobrec) def presenta_gen_msip(atr) clf = self.class.clase_llave_foranea(atr) - if self.class.columns_hash && self.class.columns_hash[atr.to_s] && - self.class.columns_hash[atr.to_s].type == :boolean - self[atr.to_s] ? "Si" : (self[atr.to_s].nil? ? "" : "No") + if self.class.columns_hash && self.class.columns_hash[atr.to_s] && + self.class.columns_hash[atr.to_s].type == :boolean + if self[atr.to_s] + "Si" + else + (self[atr.to_s].nil? ? "" : "No") + end elsif self.class.asociacion_combinada(atr) ac = self.class.asociacion_combinada(atr).name.to_s - e = self.send(ac) + e = send(ac) if e - e.inject("") { |memo, i| + e.inject("") do |memo, i| (memo == "" ? "" : memo + "; ") + i.presenta_nombre.to_s - } + end else - '' + "" end elsif clf - if (self[atr.to_s]) + if self[atr.to_s] r = clf.find(self[atr.to_s]) if r.respond_to?(:presenta_nombre) r.presenta_nombre else r.id.to_s end - elsif self.respond_to?(atr) - r = self.send(atr) + elsif respond_to?(atr) + r = send(atr) if r r.presenta_nombre else "" end else "" end - elsif self.respond_to?(atr.to_s) && - self.send(atr.to_s).respond_to?(:presenta_nombre) - self.send(atr.to_s).presenta_nombre - elsif self.respond_to?(atr.to_s) && self[atr.to_s].nil? - if self.send(atr.to_s).to_s.include?("ActiveRecord_Associations_CollectionProxy") - e = self.send(atr.to_s) - e.inject("") { |memo, i| - (memo == "" ? "" : memo + "; ") + - (i.respond_to?('presenta_nombre') ? i.presenta_nombre.to_s : i.to_s) - } + elsif respond_to?(atr.to_s) && + send(atr.to_s).respond_to?(:presenta_nombre) + send(atr.to_s).presenta_nombre + elsif respond_to?(atr.to_s) && self[atr.to_s].nil? + if send(atr.to_s).to_s.include?("ActiveRecord_Associations_CollectionProxy") + e = send(atr.to_s) + e.inject("") do |memo, i| + (memo == "" ? "" : memo + "; ") + + (i.respond_to?("presenta_nombre") ? i.presenta_nombre.to_s : i.to_s) + end else - r = self.send(atr.to_s) + r = send(atr.to_s) if !r.is_a?(Numeric) && !r.is_a?(String) r = r.to_s end r end - elsif atr == 'fechacreacion' + elsif atr == "fechacreacion" created_at - elsif atr == 'fechacreacion_localizada' - Msip::FormatoFechaHelper.fecha_estandar_local created_at - elsif atr == 'fechaactualizacion' + elsif atr == "fechacreacion_localizada" + Msip::FormatoFechaHelper.fecha_estandar_local(created_at) + elsif atr == "fechaactualizacion" updated_at - elsif atr == 'fechaactualizacion_localizada' - Msip::FormatoFechaHelper.fecha_estandar_local updated_at + elsif atr == "fechaactualizacion_localizada" + Msip::FormatoFechaHelper.fecha_estandar_local(updated_at) else self[atr.to_s].to_s end end @@ -192,75 +200,71 @@ when :actualizado_en self.updated_at = datosent[ll.to_sym] when :creado_en self.created_at = datosent[ll.to_sym] else - asig = ll.to_s + '=' - if self.respond_to?(asig) - rll = self.send(ll.to_s) - if rll && rll.class && + asig = ll.to_s + "=" + if respond_to?(asig) + rll = send(ll.to_s) + if rll&.class && rll.class.ancestors.include?(Msip::Modelo) - consr = rll.class.all.where('LOWER(UNACCENT(nombre))=LOWER(UNACCENT(?))', datosent[ll.to_sym]) + consr = rll.class.all.where("LOWER(UNACCENT(nombre))=LOWER(UNACCENT(?))", datosent[ll.to_sym]) if consr.count > 0 n = consr.take - self.send(asig, n) + send(asig, n) else - menserror << " Se buscó sin exito en tabla basica #{rll.class} el valor '#{datosent[ll.to_sym]}'." + menserror << " Se buscó sin exito en tabla basica #{rll.class} el valor '#{datosent[ll.to_sym]}'." end else begin - self.send(asig, datosent[ll.to_sym]) - rescue - menserror << " No se pudo asignar a #{ll.to_s} el valor '#{datosent[ll.to_sym]}'." + send(asig, datosent[ll.to_sym]) + rescue + menserror << " No se pudo asignar a #{ll} el valor '#{datosent[ll.to_sym]}'." end end else - menserror << " No se conoce como importar atributo " + - "'#{ll.to_s}' con valor '#{datosent[ll.to_sym]}' " + + menserror << " No se conoce como importar atributo " \ + "'#{ll}' con valor '#{datosent[ll.to_sym]}' " \ "en controlador '#{self.class}'." return nil end end end - return self + self end - # En el modelo actual crea/busca registro y lo actualiza con la # información de datosent. # @param datosent diccionario con datos de entrada (modificables) # @param datossal Diccionario con otros datos de salida # @param menserror Colchon cadena con mensajes de error # @param opciones Opciones para la importación - # @return Si lo logra retorna self si no lo logra retorna nil + # @return Si lo logra retorna self si no lo logra retorna nil # y agrega razones del error en el colchon menserror. def importa(datosent, datossal, menserror, opciones = {}) importa_gen(datosent, datossal, menserror, opciones) end - # Complementa importación una vez el modelo actual ha sido salvado # @param ulteditor_id id del usuario que importa # @param datossal Otros datos de salida de la importación que esta # función debe salvar # @param menserror colchon cadena con mensajes de error # @param opciones Para importación # @return Verdadero si logra salvar todo datossal, de lo contrario # salva lo que más puede y retorna falso def complementa_importa(ulteditor_id, datossal, menserror, opciones) - return true + true end # Por omisión es posible filtrar por id - scope :filtro_id, lambda {|id| + scope :filtro_id, lambda { |id| # Puede ser una lista de ids separadas por , - if id.include?(',') - where(id: id.split(',')) + if id.include?(",") + where(id: id.split(",")) else where(id: id) end } - end # included - end end