Reputation: 1886
sorry about the title, cannot express myself better.
I have this:
{
7758 => { 3259 => 10, 39625 => 10, 36410 => 20, 36238 => 20, 34951 => 20, 32101 => 10},
7916 => { 3259 => 10, 39625 => 10, 36410 => 20, 36238 => 20, 34951 => 20, 32101 => 10},
8857 => { 1000 => 10, 39625 => 10 }
}
the keys of those hashes represents record ids, the values represent the data that should go in their row attribute.
problem is that this hash can weigh a lot, so it's imprudent to issue an update on the database for each record represented in the hash.
instead I thought about grouping up hashes with identical values and have a structure for which I can just issue an update to records in one shot.
comparing hashes values can be done even by transforming the nested hashes themselves into a json string, since it's the datatype we use for that column.
in the end I'd like to issue an update_all
for a series of variants that has the same hash content, I understand that the number of updates issues to the database is 1:1 to how unique are the hash values, but I kinda have the choice to sort their keys in someway before the comparison should we have something smart to compare existing values rather than converting the content to a string for comparison purposes.
what happens now is a normal update on each hash record in a cycle:
UPDATE "table" SET "rates" = '{"3259":10,"39625":10,"36410":20,"36238":20,"34951":20,"32101":10}', WHERE "table"."variant_id" = 7758
UPDATE "table" SET "rates" = '{"3259":10,"39625":10,"36410":20,"36238":20,"34951":20,"32101":10}', WHERE "table"."variant_id" = 7916
UPDATE "table" SET "rates" = '{"1000":10,"39625":10}' WHERE "table"."variant_id" = 7916
I'd like to transform the original structure in something that allows me to perform this:
UPDATE "table" SET "rates" = '{"3259":10,"39625":10,"36410":20,"36238":20,"34951":20,"32101":10}', WHERE "table"."variant_id" IN(7758, 7916)
UPDATE "table" SET "rates" = '{"1000":10,"39625":10}' WHERE "table"."variant_id" = 7916
I tried a
hash.group_by { |h| h[1].to_json }.each do |rate|
but I have this in rate
:
["{\"3259\":10,\"39625\":10,\"36410\":20,\"36238\":20,\"34951\":20,\"32101\
":10}", [[7758, {3259=>10, 39625=>10, 36410=>20, 36238=>20, 34951=>20,
32101=>10}], [7916, {3259=>10, 39625=>10, 36410=>20, 36238=>20,
34951=>20, 32101=>10}], [8857, {3259=>10, 39625=>1...
Upvotes: 1
Views: 496
Reputation: 10856
Maybe something like this:
result = hash.each_with_object({}) do |(id, attributes), result|
json_string = attributes.to_json
result[json_string] ||= []
result[json_string] << id
end
result.each do |json_string, ids|
# ...
end
Upvotes: 1