Ottenere tipi di attributi in un oggetto ActiveRecord
-
25-09-2019 - |
Domanda
Vorrei sapere se è possibile ottenere i tipi (come noto da AR - ad esempio nello script di migrazione e database) programmazione (lo so medesimi dati da qualche parte).
Per esempio, io può trattare con tutti i nomi degli attributi:
ar.attribute_names.each { |name| puts name }
.attributes restituisce solo una mappatura dei nomi ai loro valori correnti (ad esempio non informazioni di tipo se il campo non è impostato).
Alcuni luoghi che ho visto con le informazioni sul tipo:
nello script / console, digitare il nome di un'entità AR:
>> Driver
=> Driver(id: integer, name: string, created_at: datetime, updated_at: datetime)
Quindi, chiaramente conosce i tipi. Inoltre, v'è .column_for_attribute, che prende il nome di attr e restituisce un oggetto di colonna - che ha il tipo sepolta nell'oggetto colonna del database sottostante, ma non sembra essere un modo pulito per ottenerlo.
Vorrei anche essere interessato a se c'è un modo che è amichevole per il nuovo "ActiveModel" che sta arrivando (Rails3) ed è disaccoppiato da specifiche del database (ma forse di tipo informazioni non sarà parte di esso, non posso' t sembra per scoprire se si tratta).
Grazie.
Soluzione
in Rails 3, per il modello di "Driver", si vuole Driver.columns_hash
.
Driver.columns_hash["name"].type #returns :string
Se si desidera iterare attraverso di loro, si farebbe qualcosa di simile:
Driver.columns_hash.each {|k,v| puts "#{k} => #{v.type}"}
quale uscita volontà il seguente:
id => integer
name => string
created_at => datetime
updated_at => datetime
Altri suggerimenti
È possibile accedere ai tipi di colonne in questo modo:
#script/console
Driver.columns.each {|c| puts c.type}
Se si desidera ottenere un elenco di tutti i tipi di colonne in un particolare modello, si potrebbe fare:
Driver.columns.map(&:type) #gets them all
Driver.columns.map(&:type).uniq #gets the unique ones
In Rails 5, si può fare questo indipendentemente dal database. Questo è importante se si utilizzano i nuovi attributi API per definire (aggiuntivo) attributi.
Come tutti gli attributi da una classe del modello:
pry> User.attribute_names
=> ["id",
"firstname",
"lastname",
"created_at",
"updated_at",
"email",...
Come il tipo:
pry> User.type_for_attribute('email')
=> #<ActiveRecord::ConnectionAdapters::AbstractMysqlAdapter::MysqlString:0x007ffbab107698
@limit=255,
@precision=nil,
@scale=nil>
Questo è a volte più informazioni del necessario. C'è una funzione di convenienza che mappa tutti questi tipi fino a un nucleo (: intero,:. Stringa etc)
> User.type_for_attribute('email').type
=> :string
Si può anche ottenere tutti i dati in una sola chiamata con attribute_types che restituisce un hash 'name': type
.
In Rails 5 questo vi darà una lista di tutti i nomi di campo insieme al loro tipo di dati:
Model_Name.attribute_names.each do |k| puts "#{k} = #{Model_Name.type_for_attribute(k).type}" end
Questo frammento di codice vi darà tutte le caratteristiche di un modello con i tipi di dati del database associati in un hash. Basta sostituire Messaggio con Active Record modello.
Post.attribute_names.map {|n| [n.to_sym,Post.type_for_attribute(n).type]}.to_h
restituirà un hash come questo.
=> {:id=>:integer, :title=>:string, :body=>:text, :created_at=>:datetime, :updated_at=>:datetime, :topic_id=>:integer, :user_id=>:integer}