Joe*_*Dyk 26 ruby postgresql activerecord
在续集中,我可以做到:
irb(main):003:0> DB["select false"].get
=> false
Run Code Online (Sandbox Code Playgroud)
返回false布尔值.我希望能够在ActiveRecord中做类似的事情:
irb(main):007:0> ActiveRecord::Base.connection.select_value "select false"
=> "f"
Run Code Online (Sandbox Code Playgroud)
如您所见,它返回字符串"f".有没有办法用ActiveRecord获取一个假布尔值?(类似地,我可能正在调用一个返回timestamptz,数组等的函数 - 我希望返回的值具有正确的类型)
我的用例:我正在调用数据库函数,想要取回一个键入的结果而不是一个字符串.
Ram*_*ord 23
虽然我毫不怀疑BjörnNilsson的答案在他发布时起作用,但对于Postgres 9.4和PG宝石版来说,它是失败的0.18.2.在查看PG gem文档后,我发现以下内容有效:
pg = ActiveRecord::Base.connection
@type_map ||= PG::BasicTypeMapForResults.new(pg.raw_connection)
res = pg.execute("SELECT 'abc'::TEXT AS a, 123::INTEGER AS b, 1.23::FLOAT;")
res.type_map = @type_map
res[0]
# => {"a"=>"abc", "b"=>123, "float8"=>1.23}
Run Code Online (Sandbox Code Playgroud)
Bjö*_*son 14
非常丑陋,但做你要求的:
res = ActiveRecord::Base.connection.
select_all("select 1 as aa, false as aas, 123::varchar, Array[1,2] as xx")
# Breaks unless returned values have unique column names
res.map{|row|row.map{|col,val|res.column_types[col].type_cast val}}
# Don't care about no column names
res.map{|row|
row.values.map.with_index{|val,idx|
res.column_types.values[idx].type_cast val
}
}
Run Code Online (Sandbox Code Playgroud)
得到:
[[1, false, "123", [1, 2]]]
Run Code Online (Sandbox Code Playgroud)
这个怎么运作:
res.column_types
Run Code Online (Sandbox Code Playgroud)
返回列名和Postgresql列类型的哈希
这是一个指向它如何工作的指针:https: //github.com/rails/docrails/blob/fb8ac4f7b8487e4bb5c241dc0ba74da30f21ce9f/activerecord/lib/active_record/connection_adapters/postgresql/oid/float.rb
没有足够的声誉点来回应,但是Bjorn的回答和相关的回复在Rails 5中被破坏.这有效:
res = ActiveRecord::Base.connection.select_all(sql)
res.to_a.map{|o| o.each{|k, v| o[k] = res.column_types[k].cast v}}
Run Code Online (Sandbox Code Playgroud)
在 Rails 6 中,Person.connection.select_all(sql_query).to_a
...将返回一个哈希数组,其值是类型转换的。例子:
[{"id"=>12, "name"=>"John Doe", "vip_client"=>false, "foo"=> nil, "created_at"=>2018-01-24 23:55:58 UTC}]
Run Code Online (Sandbox Code Playgroud)
如果您更喜欢OpenStruct,请使用迈克的建议:
Person.connection.select_all(sql_query).to_a.map {|r| OpenStruct.new(r) }
如果您更喜欢将符号作为键,请map(&:symbolize_keys)在 后调用to_a。
| 归档时间: |
|
| 查看次数: |
5454 次 |
| 最近记录: |