我有以下ActiveRecord测试用例,模仿我的问题。我有一个People表,其中一个属性是日期。我在该表上创建了一个视图,添加了一个列,即该日期加上20分钟:
#!/usr/bin/env ruby
%w|pp rubygems active_record irb active_support date|.each {|lib| require lib}
ActiveRecord::Base.establish_connection(
:adapter => "sqlite3",
:database => "test.db"
)
ActiveRecord::Schema.define do
create_table :people, :force => true do |t|
t.column :name, :string
t.column :born_at, :datetime
end
execute "create view clowns as select p.name, p.born_at, datetime(p.born_at, '+' || '20' || ' minutes') as twenty_after_born_at from people p;"
end
class Person < ActiveRecord::Base
validates_presence_of :name
end
class Clown < ActiveRecord::Base
end
Person.create(:name => "John", :born_at => DateTime.now)
pp Person.all.first.born_at.class
pp Clown.all.first.born_at.class
pp Clown.all.first.twenty_after_born_at.class
问题是,输出是
Time
Time
String
当我希望视图的新datetime属性也是ruby世界中的Time或DateTime时。有什么想法吗?
我也尝试过:
create view clowns as select p.name, p.born_at, CAST(datetime(p.born_at, '+' || '20' || ' minutes') as datetime) as twenty_after_born_at from people p;
结果相同。
答案 0 :(得分:0)
嗯,经过更多的调查,我发现:
MySQL工作:
%w|pp rubygems active_record irb active_support date|.each {|lib| require lib}
ActiveRecord::Base.establish_connection(
:adapter => "mysql",
:username => "root",
:database => "test2"
)
ActiveRecord::Schema.define do
create_table :people, :force => true do |t|
t.column :name, :string
t.column :born_at, :datetime
end
execute "create view clowns as select p.name, p.born_at, (p.born_at + INTERVAL 20 MINUTE) as twenty_after_born_at from people p;"
end
class Person < ActiveRecord::Base
validates_presence_of :name
end
class Clown < ActiveRecord::Base
end
Person.create(:name => "John", :born_at => DateTime.now)
pp Person.all.first.born_at.class
pp Clown.all.first.born_at.class
pp Clown.all.first.twenty_after_born_at.class
产地:
Time
Time
Time
读取sqlite3适配器源代码,我发现它使用PRAGMA table_info(table_name)来获取类型信息,并且不返回视图的类型:
sqlite> pragma table_info('people');
0|id|INTEGER|1||1
1|name|varchar(255)|0||0
2|born_at|datetime|0||0
sqlite> pragma table_info('clowns');
0|name|varchar(255)|0||0
1|born_at|datetime|0||0
2|twenty_after_born_at||0||0
因此,它可能是适配器的限制或只是sqlite3的视图限制。我有opened a ticket for ActiveRecord:
另外,sqlite-users中的quoting this mail:
RoR应该使用 sqlite3_column_type()确定API 从a返回的值的类型 查询。其他API如 sqlite3_column_decltype()和pragma table_info正在返回其他 信息,而不是类型 结果值。
答案 1 :(得分:0)
嗯,基本上SQLite中没有数据时类型而不是MySQL。在您的示例中,您明确定义了表的类型,但没有为视图指定类型。这可能是问题所在。因为我从未接触到红宝石,所以无法检查。