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