Last active
December 27, 2015 13:09
-
-
Save aquajach/7331330 to your computer and use it in GitHub Desktop.
[Monkey-Patch] Allow your rails4 to have a column as array of hash
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
module ActiveRecord | |
module ConnectionAdapters | |
class PostgreSQLAdapter < AbstractAdapter | |
module Quoting | |
def type_cast(value, column, array_member = false) | |
return super(value, column) unless column | |
case value | |
when Range | |
return super(value, column) unless /range$/ =~ column.sql_type | |
PostgreSQLColumn.range_to_string(value) | |
when NilClass | |
if column.array && array_member | |
'NULL' | |
elsif column.array | |
value | |
else | |
super(value, column) | |
end | |
when Array | |
case column.sql_type | |
when 'point' then PostgreSQLColumn.point_to_string(value) | |
when 'json' then PostgreSQLColumn.json_to_string(value) | |
else | |
return super(value, column) unless column.array | |
PostgreSQLColumn.array_to_string(value, column, self) | |
end | |
when String | |
return super(value, column) unless 'bytea' == column.sql_type | |
{ :value => value, :format => 1 } | |
when Hash | |
case column.sql_type | |
#aquajach: Add array_member | |
when 'hstore' then PostgreSQLColumn.hstore_to_string(value, array_member) | |
when 'json' then PostgreSQLColumn.json_to_string(value) | |
else super(value, column) | |
end | |
when IPAddr | |
return super(value, column) unless ['inet','cidr'].include? column.sql_type | |
PostgreSQLColumn.cidr_to_string(value) | |
else | |
super(value, column) | |
end | |
end | |
end | |
end | |
class PostgreSQLColumn < Column | |
module Cast | |
#aquajach: Add array_member as an option parameter | |
def hstore_to_string(object, array_member = false) | |
if Hash === object | |
object.map { |k,v| | |
"#{escape_hstore(k)}=>#{escape_hstore(v)}" | |
#aquajach: escape hstore when array_member exists | |
}.join(',').tap { |s| s.replace escape_hstore(s) if array_member } | |
else | |
object | |
end | |
end | |
def string_to_hstore(string) | |
if string.nil? | |
nil | |
elsif String === string | |
#aquajach: replace Hash with HashWithIndifferentAccess | |
HashWithIndifferentAccess[string.scan(HstorePair).map { |k,v| | |
v = v.upcase == 'NULL' ? nil : v.gsub(/\A"(.*)"\Z/m,'\1').gsub(/\\(.)/, '\1') | |
k = k.gsub(/\A"(.*)"\Z/m,'\1').gsub(/\\(.)/, '\1') | |
[k,v] | |
}] | |
else | |
string | |
end | |
end | |
end | |
end | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment