Получение типов атрибутов в объекте ActiveRecord


Я хотел бы знать, можно ли получить типы (как известно AR - eg в сценарии миграции и базе данных) программно (я знаю, что данные существуют где-то там).

например, я могу иметь дело со всеми именами атрибутов:

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

.атрибуты просто возвращает сопоставление имен с их текущими значениями (например, нет информации о типе, если поле не задано).

в некоторых местах я видел его с информацией о типе:

in скрипт / консоль, введите имя объекта AR:

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

Так ясно, что он знает типы. Кроме того, есть .column_for_attribute, который принимает имя attr и возвращает объект столбца - который имеет тип, скрытый в базовом объекте столбца базы данных, но он не кажется чистым способом его получения.

мне также было бы интересно, есть ли способ, который является дружественным для новой "ActiveModel", которая идет (rails3) и отделена от специфики базы данных (но возможно, информация о типе не будет частью этого, я не могу узнать, если это так).

спасибо.

5 59

5 ответов:

в рельсах 3, для вашей модели "водителя", вы хотите Driver.columns_hash.

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

если вы хотите перебрать их, вы бы сделали что-то вроде этого:

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

который выведет следующее:

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

Вы можете получить доступ к типам столбцов, делая это:

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

Если вы хотите получить список всех типов столбцов в определенной модели, вы можете сделать:

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

в Rails 5, Вы можете сделать это независимо от базы данных. Это важно, если вы используете API новых атрибутов для определения (дополнительных) атрибутов.

получение всех атрибутов из класса модели:

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

получаю типа:

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

это иногда больше информации, чем требуется. Есть функция удобства, которая отображает все эти типы вплоть до основного набора (:integer, :string и т. д.)

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

вы также можете получить все эти данные в один вызов с attribute_types, который возвращает a 'name': type хэш.

в Rails 5 это даст вам список всех имен полей вместе с их типа данных:

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

этот фрагмент даст вам все атрибуты модели с соответствующими типами данных базы данных в хэш. Просто замените сообщение своей активной моделью записи.

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

вернет хэш, как это.

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