Arel :: Attributes :: Attribute对象的SQL列类型

时间:2013-02-03 04:50:44

标签: ruby activerecord arel rails-activerecord

tl; dr 给定一个Arel::Attributes::Attribue对象,说Model.arel_table[:created_at]如何获取它的SQL类型?

上下文:我绕过ActiveRecord基础设施,转而使用Arel编写一些需要真正有效生成的SQL报告。使用Arel的to_sql方法我生成最终的SQL并直接通过ActiveRecord::Base.connection.execute执行它。但是,我需要将SQL转换应用于某些列(例如,更改存储在GMT中的时间戳的时区)。由于列数很大(并且根据用户输入而变化),我不想对这些转换进行硬编码。我想查看所选列的SQL类型并相应地应用转换。

2 个答案:

答案 0 :(得分:1)

如果您设置了ActiveRecord类,则可以访问其columnscolumns_hash方法。这些将为您提供列对象(ActiveRecord::ConnectionAdapters::Column的实例),您应该找到typesql_type方法。例如:

> Model.columns_hash['created_at'].type
 => :datetime 
> Model.columns_hash['created_at'].sql_type
 => "timestamp without time zone"

sql_type将是特定于数据库的(上面是PostgreSQL),type将匹配迁移中的类型,因此您可能希望使用它而不是sql_type

那就是说,你可能会使用通常的ActiveRecord关系方法(它应该为你处理转换和时区),然后在最后调用to_sql

sql = Model.where('created_at > ?', some_time).select('pancakes').to_sql

然后将该SQL提供给executeselect_rows。这将允许您使用大多数通常的ActiveRecord内容,同时避免创建一堆您不关心的ActiveRecord包装器的开销。

答案 1 :(得分:1)

type_cast_for_database是专门在竞技场中有用的东西。可以在arel表上使用:

int a(Payment payment){
 payment.setValue(payment.getValue() - 1);
 return payment.getValue() * 10;
}

虽然您没有明确获得类型,但是您可以看到诸如字符串之类的值是否将转换为数字或其他内容。

编辑

重要的是要注意,这仅在arel表具有type_caster able_to_type_cast?的情况下有效。如果从上述模型中获得它,则它应该具有类型转换程序。