web-dev-qa-db-ja.com

ActiveRecordオブジェクトの属性のタイプを取得する

型(AR-移行スクリプトやデータベースなど)をプログラムで取得できるかどうかを知りたい(データがどこかに存在することは知っている)。

たとえば、すべての属性名を処理できます。

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

.attributesは、現在の値への名前のマッピングを返すだけです(たとえば、フィールドが設定されていない場合、型情報はありません)。

型情報で見たところ:

スクリプト/コンソールで、ARエンティティの名前を入力します。

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

したがって、タイプを明確に認識しています。また、.column_for_attributeがあります。これは、attr名を取り、列オブジェクトを返します。これは、基になるデータベースの列オブジェクトに埋め込まれた型を持ちますが、それを取得するきれいな方法ではないようです。

また、来ている新しい「ActiveModel」(Rails3)に友好的で、データベースの詳細から切り離された方法があるかどうかに興味があります(しかし、おそらくタイプ情報はその一部ではないでしょう、私はそうは思えませんあるかどうかを確認してください)。

ありがとう。

61
Michael Neale

Rails 3、モデル「Driver」の場合、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
95

これを行うことにより、列のタイプにアクセスできます。

#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
21
Mike Trpcic

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 

'name': typeハッシュを返すattribute_typesを使用して、1回の呼び出しですべてのデータを取得することもできます。

16
MattW.

Rails 5では、すべてのフィールド名とそのデータ型のリストが表示されます。

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

このスニペットは、モデルのすべての属性と、関連付けられたデータベースデータタイプをハッシュで提供します。 PostをActive Recordモデルに置き換えるだけです。

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} 
1
xander-miller