rails objetos manejo lista formularios formulario clases anidados ruby-on-rails ruby activerecord activemodel

ruby-on-rails - manejo - objetos en ruby



Obtener tipos de atributos en un objeto ActiveRecord (5)

Me gustaría saber si es posible obtener los tipos (como los conoce AR, por ejemplo, en la secuencia de comandos y la base de datos de migración) de forma programática (sé que los datos existen en alguna parte).

Por ejemplo, puedo tratar con todos los nombres de atributos:

ar.attribute_names.each { |name| puts name }

.attributes simplemente devuelve una asignación de los nombres a sus valores actuales (por ejemplo, no hay información de tipo si el campo no está configurado).

Algunos lugares lo he visto con la información del tipo:

en secuencia de comandos / consola, escriba el nombre de una entidad AR:

>> Driver => Driver(id: integer, name: string, created_at: datetime, updated_at: datetime)

Entonces claramente sabe los tipos. Además, existe .column_for_attribute, que toma un nombre de attr y devuelve un objeto de columna, que tiene el tipo enterrado en el objeto de columna de base de datos subyacente, pero no parece ser una forma limpia de obtenerlo.

También me interesaría si hay una manera que sea amigable para el nuevo "ActiveModel" que viene (rails3) y esté desacoplado de las especificaciones de la base de datos (pero tal vez la información del tipo no será parte de ella, no puedo averiguar si es).

Gracias.


En Rails 3, para su modelo "Driver", desea Driver.columns_hash .

Driver.columns_hash["name"].type #returns :string

Si quieres iterar a través de ellos, harías algo como esto:

Driver.columns_hash.each {|k,v| puts "#{k} => #{v.type}"}

que dará como resultado lo siguiente:

id => integer name => string created_at => datetime updated_at => datetime


En Rails 5, puede hacer esto independientemente de la base de datos. Eso es importante si usa la nueva API de atributos para definir atributos (adicionales).

Obtener todos los atributos de una clase modelo:

pry> User.attribute_names => ["id", "firstname", "lastname", "created_at", "updated_at", "email",...

Obtener el tipo:

pry> User.type_for_attribute(''email'') => #<ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter::MysqlString:0x007ffbab107698 @limit=255, @precision=nil, @scale=nil>

A veces es más información de la necesaria. Hay una función de conveniencia que mapea todos estos tipos en un conjunto principal (: entero,: cadena, etc.)

> User.type_for_attribute(''email'').type => :string

También puede obtener todos esos datos en una sola llamada con attribute_types que devuelve un ''name'': type hash.


En Rieles 5 esto le dará una lista de todos los nombres de campo junto con su tipo de datos:

Model_Name.attribute_names.each do |k| puts "#{k} = #{Model_Name.type_for_attribute(k).type}" end


Este fragmento le dará todos los atributos de un modelo con los tipos de datos de base de datos asociados en un hash. Simplemente reemplace Post con su Modelo de registro activo.

Post.attribute_names.map {|n| [n.to_sym,Post.type_for_attribute(n).type]}.to_h

Devolverá un hash como este.

=> {:id=>:integer, :title=>:string, :body=>:text, :created_at=>:datetime, :updated_at=>:datetime, :topic_id=>:integer, :user_id=>:integer}


Puede acceder a los tipos de columnas haciendo esto:

#script/console Driver.columns.each {|c| puts c.type}

Si desea obtener una lista de todos los tipos de columnas en un Modelo en particular, puede hacer:

Driver.columns.map(&:type) #gets them all Driver.columns.map(&:type).uniq #gets the unique ones