Hash table in Rails - ruby-on-rails

I have the following hash table:
COUNTRIES = {
'France' => 'FR',
'German' => 'GE',
'United Kingdom' => 'UK'
}
I have it in my model and use it in my views so the countries are displayed as a select box. Now I have one view where I want all those values plus one more value "Europe" => 'EU' to be shown.
Meaning I would have:
COUNTRIES = {
'Europe' => 'EU',
'France' => 'FR',
'German' => 'GE',
'United Kingdom' => 'UK'
}
Now I can create a new hash table but I dont want to repeat the same values in a new table.
So, how can I re-use the same table, adding one more value just for a particular view?
All ideas are welcome.

customCountries = COUNTRIES.clone
customCountries['Europe'] = 'EU'

Try this
custom = {'Europe' => 'EU'}.merge(COUNTRIES)

"Europe".to_country!

Related

How to merge hash with activerecord relations in controller / scope

I have Item model(table) with column [id,name,notes]. then I have hash lets call it stock with column [id_of_item,total_stock],
when I do query in controller I would like to join the hash into the table as additional column so I can show the total_stock of the item.
I prefer not to use map/each (looping through all the items since the items table has thousand records. I still don't know whether this possibly or not, thank you.
if your stock is
[[1, "total_stock_1"], [2, "total_stock_2"]]
you should use
stock = Hash[[[1, "total_stock_1"], [2, "total_stock_2"]]]
to translate your hash to this style
stock = {1 => "total_stock_1", 2 => "total_stock_2"}
stock = {1 => "total_stock_1", 2 => "total_stock_2"}
#items = Item.all.map{|item| item.attributes.merge({total_stock: stock[item.id]})}
# the output will be a json not a ActiveRecordRelation
[
{:id => 1, :name => 'item1', :notes => xxx, :total_stock => "total_stock_1"},
{:id => 2, :name => 'item2', :notes => yyy, :total_stock => "total_stock_2"}
]
You can do this in controller:
#items = Item.all
render json: #items.map{|item| {'item': item.as_json.merge stock.select{|item| item['id_of_item'] == item.id}['total_stock']} }}

Grabbing a specific hash in an array that meets a specific criteria

I have a huge array full of a bunch of hashes. What I need to do is single out one index hash from the array that meets a specific criteria. (doing this due to an rspec test, but having trouble singling out one of them)
My array is like this
[
{
"name" => "jon doe",
"team" => "team2",
"price" => 2000,
"eligibility_settings" => {}
},
{
"name" => "jonny doe",
"team" => "team1",
"value" => 2000,
"eligibility_settings" => {
"player_gender" => male,
"player_max_age" => 26,
"player_min_age" => 23,
"established_union_only" => true
}
},
{
"name" => "jonni doe",
"team" => "team3",
"price" => 2000,
"eligibility_settings" => {}
},
]
I need to single out the second one, based on its eligibility settings. I just took three of them from my array, have lots more, so simple active record methods like (hash.second) won't work in this instance.
I've tried things like
players.team.map(&:hash).find{ |x| x[ 'eligibility_settings?' ] == true}
However when I try this, I get a nil response. (which is odd)
I've also looked into using the ruby detect method, which hasn't gotten me anywhere either
Players.team.map(&:hash).['hash.seligibiltiy_settings'].detect { true }
Would anybody have any idea what to do with this one?
Notes
players.team.map(&:hash).find{ |x| x[ 'eligibility_settings?' ] == true}
Players.team.map(&:hash).['hash.seligibiltiy_settings'].detect { true }
Is is players or Players ?
Why is it plural?
If you can call map on team, it probably should be plural
Why do you convert to a hash?
eligibility_settings? isn't a key in your hash. eligibility_settings is
eligibility_settings can be a hash, but it cannot be true
If you want to check if it isn't empty, use !h['eligibility_settings'].empty?
Possible solution
You could use :
data = [
{
'name' => 'jon doe',
'team' => 'team2',
'price' => 2000,
'eligibility_settings' => {}
},
{
'name' => 'jonny doe',
'team' => 'team1',
'value' => 2000,
'eligibility_settings' => {
'player_gender' => 'male',
'player_max_age' => 26,
'player_min_age' => 23,
'established_union_only' => true
}
},
{
'name' => 'jonni doe',
'team' => 'team3',
'price' => 2000,
'eligibility_settings' => {}
}
]
p data.find { |h| !h['eligibility_settings'].empty? }
# {"name"=>"jonny doe", "team"=>"team1", "value"=>2000, "eligibility_settings"=>{"player_gender"=>"male", "player_max_age"=>26, "player_min_age"=>23, "established_union_only"=>true}}
If h['eligibility_settings'] can be nil, you can use :
data.find { |h| !h['eligibility_settings'].blank? }
or
data.find { |h| h['eligibility_settings'].present? }

How can I use bulk insert in the case

how can I use bulk insert from array in Rails, like below:
name_list = [{"id" => 1,"name" => "bob"},{"id" => 2,"name" => "ted"}]
Namelist.import name_list
I can`t insert values of above array.
You can do that in single insert query using activerecord-import gem.
name_list = [{"id" => 1,"name" => "bob"},{"id" => 2,"name" => "ted"}]
namelist_objects = []
name_list.each do |n|
namelist_objects << Namelist.new(n)
end
Namelist.import(namelist_objects)
The above answers of others will work fine but name_list.size number of insert queries will run which is not feasible when the array is big.
Hope that helps!
You can just pass the array of hash to create
Namelist.create([{id: 1, name: "bob"}, {id: 2, name: "ted"}])
I am not sure what you want, but maybe it will help you. I think you want create Namelist for both name_lists, isn't ?
name_list = [{"id" => 1,"name" => "bob"},{"id" => 2,"name" => "ted"}]
name_list.map{|k| Namelist.create(k) }

Merging Two Hashses

I am using the Google Civic Information API. It is giving me two arrays of hashes. I want to print information from both on the screen. Hash 1 has some integers as a k-v pair (officialIndices). These represent the index number for the corresponding object in the second hash. How can merge these two? I want to display the information from both hashes together. Maybe it would be better to replace the values of officialIndices with the indexed hash in the second array. Thanks for any advice!
Hash 1:
{
"name" => "President of the United States",
"divisionId" => "ocd-division/country:us",
"levels" => ["country"],
"roles" => ["headOfState", "headOfGovernment"],
"officialIndices" => [0]
}
Hash 2:
{
"name" => "Barack Obama",
"address" => [{
"line1" => "The White House",
"line2" => "1600 pennsylvania avenue nw",
"city" => "washington",
"state" => "DC",
"zip" => "20500"
}],
"party" => "Democratic",
"phones" => ["(202) 456-1111"],
"urls" => ["http://www.whitehouse.gov/"],
"photoUrl" => "http://www.whitehouse.gov/sites/default/files/imagecache/admin_official_lowres/administration-official/ao_image/president_official_portrait_hires.jpg",
"channels" => [
{ "type" => "GooglePlus", "id" => "+whitehouse" },
{ "type" => "Facebook", "id" => "whitehouse" },
{ "type" => "Twitter", "id" => "whitehouse" },
{ "type" => "YouTube", "id" => "barackobama" }
]
}
EDIT** To clarify, Hash 1 is the first hash in an array of hashes. Hash 2 is the first hash in an array of hashes. I would like to replace the number in officialIndice in Hash 1 with Hash 2. It's confusing me because some officialIndices have more than one number. Hope that makes sense.
Merge won't work; what will you do if officialIndices has multiple elements?
array1.each do |el1|
el1["officials"] = el1["officialIndices"].map { |idx|
array2[idx]
}
el1.delete("officialIndices")
end
(Note: this is destructive, i.e. it will change array1. If you want array1 unchanged, I'll rewrite.)
You can use Hash#merge with a block:
foo = { "name" => "President of the United States" }
bar = { "name" => "Barack Obama" }
foo.merge(bar) { |key, old_val, new_val| {description: old_val, value: new_val} }
=> {"name"=>{:description=>"President of the United States",
:value=>"Barack Obama"}}
So, you can specify your merge logic by this way. This solution effective if you have more than 1 overlapping key with similar logic.
You can use Hash#merge to merge information from two hashes. However, you have an overlapping key (name) in both, so you'll want to rename it either hash before merging:
# Rename "name" to "position_name" before merging to prevent collision
hash1["position_name"] = hash1.delete("name")
merged_hash = hash1.merge(hash2)

create a specific hash (dynamic)

How I can create a hash like this in a cycle ?
User.items.each do |m|
......
Result:
test = [{:name => 'Unit 1', :price => "10.00"},
{:name => 'Unit 2', :price => "12.00"},
{:name => 'Unit 3', :price => "14.00"}]]
You can use map to return hashes that you build.
Assuming your Item resource responds to name and price, it would look like
test = User.items.map do |m|
{
name: m.name,
price: m.price
}
end
You also can do like this:
Item.connection.select_all("select name, price from items where user_id = xxxxx;")
you will get an array containing hash, like this:
[{"name"=>"xxx", "price"=> xxx},{}......]

Resources