How to manipulate hash keys to transform numeric months to names - ruby-on-rails

I have an AR query that returns a hash of events per month, ordered by month
o.events.group("to_char(date,'MM')").order("to_char(date,'MM')").size()
I'm using numeric months in this query as it was the best way I could find to get things in the correct order, and I also need to do some other manipulations on the hash.
Before display the results, I need to convert the numeric months back to words. I added the following to the end of the query
.each_key{ |key| Date::MONTHNAMES[key] }
But i get
TypeError: can't convert String into Integer.
So i tried
.each_key{ |key| Date::MONTHNAMES[key.to_i] }
But the months remain in numeric form
{"01"=>4, "02"=>3.....
How can i manipulate this hash to get
{"January"=>4, "February"=>3.....

Make a new Hash. If you can't, make a new key in the current hash and delete the original key. You can't simply change a key, since key is a local variable in the block, and changing it in no way impacts the contents of the Hash.

This ? :
def number_to_month(number)
(Time.now.beginning_of_year + number.months).strftime("%B")
end

There are ways to generate a new hash but I think you could just convert the strings to month names in your view right before displaying them. Use the code you already wrote inside the block in your question but put it in your view.

Related

Get nested values from a hash using single string

I have a string that represents a sequence of keys in a nested hash in the following format:
keys = 'key1[key2]'
and a nested hash that has the corresponding keys like the following:
hash = {key1: {key2: 'value'}}
Is there any way to get the value from this hash directly as in the following?
value = hash[keys]
Or, do I have to write my own logic?
hash.dig(*keys.delete(']').split('[').map(&:to_sym))
To answer your specific question, No, there is no way (to my knowledge) to get the value from hash directly by passing your input string.
You will have to write your own logic to extract the keys from string and then fetch the value.

Having different count per key in jsonb

I have values in a table called Translation, that contains for every values per example:
=> {"fr"=>"Jaune", "de"=>"", "en"=>"", "bg"=>"", "hr"=>"", "es"=>"", "hu"=>"", "it"=>"", "lt"=>"", "lv"=>"", "nl"=>"", "pl"=>"", "pt"=>"", "ro"=>"", "cs"=>""}
and I'm looking to get the the number of the translation for each language:
I'm trying :
Translation.where("values->>'fr' IS NOT NULL").count
but it giving me 0, which is not correct, do anyone knows how to do it correctly?
The problem that you have is that the keys that don't have values, still exist in the json, so "is not null" will return all of them because the key exist. you have two options here, you can remove the empty keys from the database, so not null will work, or, change it to see if the key is empty
You can do it like this
Translation.where("values->>'fr' <> ''").count
and it will work with the structure that you have right now.

What is simplest way to convert :pluck or :collect results to array of strings in Rails?

I have a model called Record and belongs Product model,
the price column type is hexadecimal. Rails already convert it to string in view. But I wanna get them in my console queries.
Example code for pluck:
Product.first.records.pluck(:price)
This query displays the values in array as hexadecimal. There is a method called to_sentences for pluck values but its not enough for my case.
The problem is same in collect method:
Product.first.records.collect(&:price)
What is the pluck query to display my hexadecimal data as array of strings like:
["45,46","75,42"]
Product.first.records.pluck(:price).map(&:to_s)
please try this:
Product.first.records.pluck(:price).join(',')

Construct a Hash collection that can be sorted by time of insertion

From time to time I'm inserting key-value pairs to a Hash.
How can I construct this Hash such that I can sort the pairs by the Time they were created?
If I create a nested Hash where the key would be a timestamp (in String format I suppose) and the value the value-key pair - would that be "easy" to sort chronologically then or is there any better way?
Hash already behaves like that. Basically, the elements are ordered based on the time you inserted the element.
Hashes enumerate their values in the order that the corresponding keys were inserted.
Source
You can simply set your keys as a timestamps each time you insert a value to your hash.
For ex:
your_hash = {}
unique_timestamp = Time.now.to_s #time key as a string (you can create it each time
#you want to insert a value)
your_hash[unique_timestamp] = "new_value"
So, you can inspect your hash like "your_hash.inspect" and you will see your key as a string timestamp format and then your value.

jRuby / Rails sort hash by another hash value

I have a hash that will render my html differently based on a particular variable. The variable is within the hash. So I am wondering how I can pass a hash value to a group by. to sort the rest heres what I am trying, maybe this will explain it better than me wording it.
<% grouped = svcs.group_by { |svc| svc[val[:sorttype]] } %>
val is a multidimensional hash. the first 2 key value pairs sorttype and one other are simple key and value, the 3rd piece (svcs) contains the equivilent of a 2D hash. Which if I manually type the type of sort I want to apply to it for the group by it works ie:
<% grouped = svcs.group_by { |svc| svc[:service_name] } %>
in PHP i know in a similar instance I can pass a variable of some sort to something like this and have it work. I assume such is the case here. However Im not sure how to put the variable in. Cause all the ways Ive tried don't work
It depends a little.
Rails' has a HashWithIndifferentAccess that will not distinguish between string and symbol keys; if you're using one of those, it should work as-is.
If it's not, it depends what the val entries are--if they're strings, convert to a symbol using to_sym, e.g., svc[val[:sorttype].to_sym].

Resources