Ruby Arel::Attributes::Attribute对象中的SQL列类型
tl;dr给定一个Ruby Arel::Attributes::Attribute对象中的SQL列类型,ruby,activerecord,arel,rails-activerecord,Ruby,Activerecord,Arel,Rails Activerecord,tl;dr给定一个Arel::Attributes::Attribue对象,比如Model.Arel\u table[:created\u at]如何获取它的SQL类型 上下文:我绕过ActiveRecord基础设施,转而使用Arel编写一些需要高效生成的SQL报告。使用Arel的to_sql方法,我生成最终的sql,并通过ActiveRecord::Base.connection.execute直接执行它。但是,我需要对某些列应用SQL转换(例如,更改存储在GMT中的时间戳的时区)。由于列的数
Arel::Attributes::Attribue
对象,比如Model.Arel\u table[:created\u at]
如何获取它的SQL类型
上下文:我绕过ActiveRecord基础设施,转而使用Arel编写一些需要高效生成的SQL报告。使用Arel的
to_sql
方法,我生成最终的sql,并通过ActiveRecord::Base.connection.execute直接执行它。但是,我需要对某些列应用SQL转换(例如,更改存储在GMT中的时间戳的时区)。由于列的数量很大(并且根据用户输入而变化),我不想硬编码这些转换。我想查看所选列的SQL类型,并相应地应用转换。如果设置了ActiveRecord类,则可以访问其列和列\u散列方法。这些将为您提供列对象(ActiveRecord::ConnectionAdapters::column
)的实例,在那里您应该可以找到type
和sql\u type
方法。例如:
> Model.columns_hash['created_at'].type
=> :datetime
> Model.columns_hash['created_at'].sql_type
=> "timestamp without time zone"
sql\u类型
将是特定于数据库的(即上面的PostgreSQL),类型
将与迁移中的类型匹配,因此您可能希望使用该类型而不是sql\u类型
这就是说,您可能不需要使用通常的ActiveRecord关系方法(它应该为您处理转换和时区),然后在最后调用到_sql
:
sql = Model.where('created_at > ?', some_time).select('pancakes').to_sql
然后将该SQL输入execute
或select\u rows
。这将允许您使用大多数常用的ActiveRecord内容,同时避免创建一堆您不关心的ActiveRecord包装的开销。在arel中可能特别有用的东西是。这可用于arel工作台:
Model.arel_table.type_cast_for_database(:id, 'test')
=> 0
Model.arel_table.type_cast_for_database(:id, '47test')
=> 47
虽然您没有得到特定的类型,但是您可以看到字符串之类的值是否将被转换为数字或其他内容
编辑
重要的是要注意,这仅在arel工作台具有类型_脚轮时有效。如果你从上面的模型得到它,它应该有一个类型脚轮