Ruby-on-rails 获取 ActiveRecord 对象中的属性类型
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2399556/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Getting types of the attributes in an ActiveRecord object
提问by Michael Neale
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.
谢谢。
回答by Grant Birchmeier
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
回答by Mike Trpcic
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
回答by Matthias Winkelmann
In Rails 5, you can do this independently of the Database. That's important if you use the new Attributes API to define (additional) attributes.
在 Rails 5 中,您可以独立于数据库执行此操作。如果您使用新的 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': typehash.
您还可以使用返回'name': type哈希值的attribute_types 在一次调用中获取所有数据。
回答by Amin
In rails 5 this will give you a list of all field names along with their data type:
在 rails 5 中,这将为您提供所有字段名称及其数据类型的列表:
Model_Name.attribute_names.each do |k| puts "#{k} = #{Model_Name.type_for_attribute(k).type}" end
回答by xander-miller
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}
回答by estani
Rails 5+ (works with virtual attributes as well):
Rails 5+(也适用于虚拟属性):
Model.attribute_types['some_attribute'].type
回答by Michael Minter
In Rails 4 You would use Model.column_types.
在 Rails 4 中,您将使用Model.column_types。

