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) }
Related
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']} }}
I have situation like this:
clients = {
"yellow"=>[{"client_id"=>"2178","price" => 1},{"client_id" => "2282","price" => 2}],
"orange"=>[{"client_id"=>"2180","price" => 1},{"client_id" => "2283","price" => 3}],
"red"=>[{"client_id"=>"2178","price" => 1},{"client_id" => "2282","price" => 3}],
"blue"=>[{"client_id"=>"2180","price" => 1},{"client_id" => "2283","price" => 1}]
}
I need to get the key(s) with client ids => [2282,2178] and get the lowest key value based on price.
How can I achieve this?
res = []
client.each{|k, v|
res << k if v.detect{|hash| hash["client_id"] == "2282"}
}
res
#=> ["red", "yellow"]
NOTE
This answer is for OPs original question that required finding keys that contained "client_id" = 2282. I have not updated my answer as OP changed the requirement quite lazily.
currently I am creating a JSON object as follows:
#comments = Array.new
comments.collect do |comment|
#comments << {
:id => comment.id,
:content => html_format(comment.content),
:created_at => comment.created_at
}
end
#comments.to_json
And this returns something like this:
[{"created_at":"2011-03-02T09:17:27-08:00","content":"<p>Random.......</p>","id":734}, {"created_at":"2011-03-02T09:17:27-08:00","content":"<p>asdasd.......</p>","id":714}, {"created_at":"2011-03-01T09:17:27-08:00","content":"<p>Random.......</p>","id":134}, {"created_at":"2011-03-01T02:17:27-08:00","content":"<p>dasdasdasdasd.......</p>","id":3124}]
Problem here is that I need to include a few other items that aren't arrays. What I would like is the JSON object to look something like this:
[comments: {"created_at":"2011-03-02T09:17:27-08:00","content":"<p>Random.......</p>","id":734}, {"created_at":"2011-03-02T09:17:27-08:00","content":"<p>asdasd.......</p>","id":714}, {"created_at":"2011-03-01T09:17:27-08:00","content":"<p>Random.......</p>","id":134}, {"created_at":"2011-03-01T02:17:27-08:00","content":"<p>dasdasdasdasd.......</p>","id":3124}, last_load: "123123123123", last_view: "zxczcxzxczxc"]
Any ideas on how I can take what I have above, and expand it to pass additional items other than the comments array?
Thank you!
Add your list to a hash, and then call to_json on the hash.
> a = [1,2,3]
=> [1, 2, 3]
> h = {:comments => a, :foo => "bar"}
=> {:foo=>"bar", :comments=>[1, 2, 3]}
> h.to_json
=> "{\"foo\":\"bar\",\"comments\":[1,2,3]}"
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!
I would like to turn a string with opening hours like this:
"Monday-Friday>10:00-18:00;Saturday>12:00-17:00;Sunday>12:00-15:00"
Into this:
[ {:period => "Monday-Friday", :hours => "10:00-18:00"}, {:period => "Saturday", :hours => "12:00-17:00"}, {:period => "Sunday", :hours => "12:00-15:00"} ]
I'm trying it with the String.scan() method but can't figure out the Regexp.
Also if you have any suggestions of how to do it in reverse the best way (i.e. when getting the opening hours from a form.)
Update - Thank you all found perfect solutions! Right now I'm using (thanks kejadlen):
str.scan(/([\w-]+)>([\d:-]+)-([\d:]+)/).map { |(p,o,c)| {:period => p, :opens => o, :closes => c} }
But now how about reversing it =) So given:
[ {:opens=>"10:00", :closes=>"18:00", :period=>"Monday-Friday"},
{:opens=>"12:00", :closes=>"17:00", :period=>"Saturday"},
{:opens=>"12:00", :closes=>"15:00", :period=>"Sunday"} ]
I want to merge it to:
"Monday-Friday>10:00-18:00;Saturday>12:00-17:00;Sunday>12:00-15:00"
If you prefer one-liners:
s = "Monday-Friday>10:00-18:00;Saturday>12:00-17:00;Sunday>12:00-15:00"
s.split(/;/).map{|i| Hash[[[:period, :hours], i.split(/>/)].transpose]}
# or
s.split(/;/).map{|i| p, h = i.split(/>/); {:period => p, :hours => h}}
#=> [{:period=>"Monday-Friday", :hours=>"10:00-18:00"}, {:period=>"Saturday", :hours=>"12:00-17:00"}, {:period=>"Sunday", :hours=>"12:00-15:00"}]
Edit:
Regarding the reverse, this should do the job:
a.map{|i| "#{i[:period]}>#{i[:opens]}-#{i[:closes]}"}.join(';')
=> "Monday-Friday>10:00-18:00;Saturday>12:00-17:00;Sunday>12:00-15:00"
this is how I would do it
str="Monday-Friday>10:00-18:00;Saturday>12:00-17:00;Sunday>12:00-15:00"
periods = str.split(';')
#=> ["Monday-Friday>10:00-18:00", "Saturday>12:00-17:00", "Sunday>12:00-15:00"]
period_array=[]
periods.each do |period|
period_with_hours = period.split('>')
period_array << {:period => period_with_hours.first, :hours => period_with_hours.last}
end
period_array
#=> [{:period=>"Monday-Friday", :hours=>"10:00-18:00"}, {:period=>"Saturday", :hours=>"12:00-17:00"}, {:period=>"Sunday", :hours=>"12:00-15:00"}]
Try this:
String S = ([^\>]*)\>([^\;]*)\;
String T = " {:period => $1, :hours => $2}, "
originalString.replaceAll(S,T);
Might have to play with the regexp a little more but that should about do it.
Edit - Well, you asked for the answer in the context of ruby and I gave you the Java answer but the regular expression should work anyway...
This looks like it works
the_input.split(';').collect{|pair|
period, hours = pair.split('>')
{:period => period, :hours => hours}
}
=> [{:hours=>"10:00-18:00", :period=>"Monday-Friday"}, {:hours=>"12:00-17:00", :
period=>"Saturday"}, {:hours=>"12:00-15:00", :period=>"Sunday"}]
str.scan(/([\w-]+)>([\d:-]+)/).map {|(p,h)| {:period => p, :hours => h }}