简体   繁体   English

获取 ActiveRecord 对象中的属性类型

[英]Getting types of the attributes in an ActiveRecord object

I would like to know if it is possible to get the types (as known by AR - eg in the migration script and database) programmatically (I know the data exists in there somewhere).我想知道是否有可能以编程方式获取类型(如 AR 所知 - 例如在迁移脚本和数据库中)(我知道数据存在于某处)。

For example, I can deal with all the attribute names:例如,我可以处理所有属性名称:

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

.attributes just returns a mapping of the names to their current values (eg no type info if the field isn't set). .attributes 只返回名称到其当前值的映射(例如,如果未设置该字段,则没有类型信息)。

Some places I have seen it with the type information:我在一些地方看到过它的类型信息:

in script/console, type the name of an AR entity:在脚本/控制台中,输入 AR 实体的名称:

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

So clearly it knows the types.所以很清楚它知道类型。 Also, there is .column_for_attribute, which takes an attr name and returns a column object - which has the type buried in the underlying database column object, but it doesn't appear to be a clean way to get it.此外,还有 .column_for_attribute,它采用 attr 名称并返回一个列对象 - 其类型隐藏在底层数据库列对象中,但它似乎不是一种干净的获取方式。

I would also be interested in if there is a way that is friendly for the new "ActiveModel" that is coming (rails3) and is decoupled from database specifics (but perhaps type info will not be part of it, I can't seem to find out if it is).我也很想知道是否有一种方法对即将到来的新“ActiveModel”(rails3)友好并且与数据库细节分离(但也许类型信息不会成为其中的一部分,我似乎无法看看是不是)。

Thanks.谢谢。

In Rails 3, for your model "Driver", you want Driver.columns_hash .在 Rails 3 中,对于您的模型“驱动程序”,您需要Driver.columns_hash

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

If you want to iterate through them, you'd do something like this:如果你想遍历它们,你会做这样的事情:

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

which will output the following:这将输出以下内容:

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

In Rails 5, you can do this independently of the Database.在 Rails 5 中,您可以独立于数据库执行此操作。 That's important if you use the new Attributes API to define (additional) attributes.如果您使用新的 Attributes API 来定义(附加)属性,这一点很重要。

Getting all attributes from a model class:从模型类中获取所有属性:

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

Getting the type:获取类型:

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

That's sometimes more information than needed.这有时比需要的信息多。 There's a convenience function that maps all these types down to a core set (:integer, :string etc.)有一个方便的函数可以将所有这些类型映射到一个核心集(:integer, :string 等)

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

You can also get all that data in one call with attribute_types which returns a 'name': type hash.您还可以使用 attribute_types 在一次调用中获取所有数据,该调用返回'name': type哈希。

You can access the types of the columns by doing this:您可以通过执行以下操作访问列的类型:

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

If you want to get a list of all column types in a particular Model, you could do:如果要获取特定模型中所有列类型的列表,可以执行以下操作:

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

在 rails 5 中,这将为您提供所有字段名称及其数据类型的列表:

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

This snippet will give you all the attributes of a model with the associated database data types in a hash.此代码段将为您提供一个模型的所有属性以及哈希中关联的数据库数据类型。 Just replace Post with your Active Record Model.只需将 Post 替换为您的 Active Record 模型。

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

Will return a hash like this.将返回这样的哈希值。

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

Rails 5+(也适用于虚拟属性):

Model.attribute_types['some_attribute'].type

在 Rails 4 中,您将使用Model.column_types

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM