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].
Related
I dont how to accomplish this problem.
I faced with this problem 3 times and each time I put it in my todo list but even tho I tried to find a solution I couldnt.
For examples,
I m trying to create a query with dynamic variables of this example;
User.search(first_name_start: 'K')
there are 3 arguments in this example;
1)first_name - My model attribute
2)start - Query type (start/end/cont )
3)'3' - value
I was able to create dynamic ActiveRecord using static symbols but how am I suppose to make dynamic input
Thanks in advance
EDIT: ADDITIONAL INFORMATION
let me show you a some kind of pseudo-code
varArray.each_with_index |x,index|
queryString=varArray[i]+"_"+filterArray=[i] #lets say varArray[i], this will be first_name, an actual model attribute/a column in my db
#and filterArray like /start/end/with a filter type
#and finally valArray a string value like 'geo' or 'paul'
User.where(queryString valArray[i]).result
I tried to use send(variable) but that didnt help me either, so i dont how should i proceed,
This is one of a few cases where new fancy Ruby 1.9 syntax for defining hashes doesn't cut it. You have to use the traditional hashrocket (=>) that allows you to specify not only symbols, but any arbitrary values as hash keys:
column = "#{first_name}_size_#{query_type}".to_sym
User.where( column => value )
AFAIK, ActiveRecord is able to accept strings instead of symbols as column names, so you don't even need to call to_sym.
I have an array with keys that I use to create options for a drop down
FEEDBACK_NOTIFICATION = [['Only in reports', 'only_in_reports'],['Immediately', 'immediately']]
<%= f.select(:feedback_schedule, options_for_select(FEEDBACK_NOTIFICATION)) %>
The first values ('Only in reports', 'Immediately') are displayed in the drop down but the last value is stored in the database ('only_in_reports' or 'immediately').
When I want to show the value in a view I am doing something like this:
REPORT_SCHEDULE.select {|v,k| k==#company.report_schedule}.first.first
Is there not an easier way to retrieve a value from a key pair array?
Slightly better:
REPORT_SCHEDULE.find { |v, k| k == #company.report_schedule }.first
Personally, I would however store the "translations" in a yaml file, following the I18n conventions, as shown in my answer on question Translating activerecord collection for a dropdown
This way, your "representation" is nicely separated from the rest of your code
This should do.
Hash[REPORT_SCHEDULE][#company.report_schedule]
My goal is to determine whether there is a blank in a hash like this:
{"departure_time_slots"=>{"date"=>[""], "time"=>{"start"=>[""], "end"=>[""]}}}
The strings are nested arbitrary times. I do not want to check each of them manually. It would be nice if I can extract all the strings regardless of their depth. Is there a simple way to do that?
Here's an example of how you can extract the values. However you will still have the problem of matching the values to the keys. You can't really have both at the same time.
# Extend the Hash class
class Hash
def recursive_values
self.values.collect { |v|
v.is_a?(Hash) ? v.recursive_values : v
}.flatten
end
end
Usage:
h = {"departure_time_slots"=>{"date"=>[""], "time"=>{"start"=>[""], "end"=>[""]}}}
h.recursive_values
=> ["", "", ""]
It will be better if you will use sth like that:
departure_time_slots = {:date => Time.new, :time_start => nil, :time_end => nil}
And when you use keys in Hash it is good practise to using Symbols for keys. (http://www.ruby-doc.org/core-1.9.3/Symbol.html)
No not possible. Because they are totally present in different scope with respect to each other.
For e.g.. keys start and end is totally unknown and masked from the departure_time_slots object in the example above.
One round abut way could be, getting all the values of the hashmap which are of type hashmap again and obtaining their keys recusively.
Fetch keys of departure_time_slots and then from the value list of that map, find all the keys from every value, if that were to be a hashmap. Other than that, I don't think there is another way.
P.S. On side note, see if u can modify your structure to an array where elements can also be arrays, and try and use flatten concept of arrays. :P
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.
I'm building an xml document from a hash. The xml attributes need to be in order. How can this be accomplished?
hash.to_xml
Ruby 1.8's hash aren't in insertion order. With ruby 1.9, they will be.
However rails offers an alternative to that, the class OrderedHash.
my_hash = ActiveSupport::OrderedHash.new
my_hash[:key] = 'value'
my_hash[:second_key] = 'second value'
This hash is in fact an array of that format :
[[:key, 'value'], [:second_key, 'second value']]
The entries remains in the order you inserted them.
And you can access them like with any other hash.
h = Hash[:x,123,:a,553,:d,949,:e,5321]
=> {:e=>5321, :x=>123, :a=>553, :d=>949}
h.sort { |x,y| x[0].to_s <=> y[0].to_s }
=> [[:a, 553], [:d, 949], [:e, 5321], [:x, 123]]
The usual ways of sorting a hash is by key or value. Have a look here:
hash.sort
More complex sorts can be accomplised however by utilizing the spaceship operator
What order did you want them to be in? You shouldn't expect them to be in insertion order. From the docs for Hash:
The order in which you traverse a hash
by either key or value may seem
arbitrary, and will generally not be
in the insertion order.
If you need them to be in a specific order you can determine just from the keys/values (e.g. order the attribute names alphabetically), you'll need to apply that ordering explicitly.
This piece of code I've just made for i18n-js might help you out as it convert Hash to ActiveSupport::OrderedHash if needed then sort it's key by natural order.
http://seb.box.re/2010/1/15/deep-hash-ordering-with-ruby-1-8