I have a table on Db with two fields: group and text
I want to retrieve all records and convert into an hash grouped by the group field, and containing an array of all texts, something like this:
{
'group_1': ['text1','text2',...]
'group_2': ['text1','text2',...]
'group_3': ['text1','text2',...]
}
I acomplish it partially with this
MyModel.all.group_by(&:group)
but it returns an array with all the full AR object, i just want an array of all the text strings
I was trying with map but I can figure out how to do this without using each
Any idea?
Try the following:
MyModel.all.select([:text, :group]).group_by(&:group)
If you wanted to use an iterator (ex: each/map), here is how you would do it:
grouped_models = MyModel.all.group_by(&:group)
grouped_models.map do |group, models|
grouped_models[group] = models.map(&:text)
end
grouped_models
# => { 'group_1' => ['text1', 'text2'], 'group_2' => ['text'] }
Related
I save an array of strings to my rails database, but when I go to use it in the view, I believe it is printing the string definition of the array. Am I dealing with JSON here? (aka when it saves to the database is it just an array wrapped in a string?)
How do I have it so that in my view, it simply displays the items?
<%= record.items %>
displays inside my html tag:
["item1", "item2", "item3"]
I tried iterating through record.items.each do |item| but that did not work.
If you're saving an "exact" array as a String, then Array#each won't work, because isn't a method in the String class.
Maybe isn't the best option, but you could use JSON.parse and this way get your array and be able to iterate over each object inside:
require 'json'
str = '["item1", "item2", "item3"]'
JSON.parse(str).each { |item| p item }
# "item1"
# "item2"
# "item3"
In order this work your string must be an array, in your example the second item is missing its double quote.
You could consider working with serialization or array data types depending on you current database.
A better approach to your issue is to serialize your items column. I think by default it's Array but you can use Hash or JSON.
class Record < ActiveRecord::Base
serialize :items
end
Calling record.items returns the data exactly the way you need. If you go with this you'll have to update your old records to support it.
I have a Model that is called teams.
When I do Teams.account_ids it returns something like:
[{"_id"=>"145952912234658", "_type"=>"Page"},
{"_id"=>"465641870160985", "_type"=>"Account"}]
Lets say I want to get all Teams that have one specific account id regardless of its _type.
Something like:
Team.where(some_id.in => account_ids.map{|k| k["_id"))
You can use multi-keys to effectively ignore the array when searching and then use the standard "key inside a hash" notation to look at the _ids:
Teams.where('account_ids._id' => { :$in => array_of_ids })
I want to display value of collection by passing their respective attribute name.
#mandates is the result of an active-record query.
#tabattributes contains array of attribute names previously selected by users.
The code below show field attributes but I want the value of these field instead.
I've tried several syntaxes but errors occurs each time.
How can I modify my code to do that?
#mandates.map do |f|
#tabattributes.each { |att| " #{att} "}
end
If #mandates is a result set that contains models with attributes a, b, and c and #tabattributes is the array %w{a b} (i.e. you want to extract a and b from each element of #mandates) then:
a = #mandates.map { |m| m.attributes.slice(*#tabattributes) }
will give you an array of hashes with keys 'a' and 'b'. For example:
#tabattributes = %w{id created_at}
slices = #mandates.map { |m| m.attributes.slice(*#tabattributes) }
# slices is now like [ { 'id' => ..., 'created_at' => ... }, ... ]
If you only want the values and don't care about the keys then perhaps this will work for you:
#mandates.map { |m| m.attributes.slice(*#tabattributes).values }
That would give you an array-of-arrays. The first array-of-hashes would probably be easier to work with though.
If you can get at #mandates before accessing the database then you could slice out just the columns you're interested inside the database with something like this:
#mandates = Mandate.select(#tabattributes)
slices = #mandates.map(&:attributes)
If I understand you right, you have an array of elements, and you want to have an array containing the name of each element, is that it ? If yes, then array.map {|elem| elem.name} should do it. There is a shorter form (array.map(&:name)) which does the same, if you're interested in how this is working, I can detail.
How can I read everything inside a JSON document and create another one with new names?
I can't find something that will help me create a new JSON file in an easy way.
Edit:
I am retrieving a ton of data in JSON format from a MongoDB database (as an array [{"xxx": "zz"}, ... ]). What I need is to cycle trough each document, each field and create a new JSON document using those fields.
thanks
Here's the gist of what you want:
#keys = {
"old" => "new",
"foo" => "bar"
}
def rename_key(pair)
old_key = pair.keys.first
{ #keys[old_key] => pair[old_key] }
end
pairs = ActiveSupport::JSON.decode(json)
pairs.map! { |pair| rename_key(pair) }
new_json = pairs.to_json
Obviously, you'd want to turn this into a class or two. Note that I made the assumption that all data from Mongo was in the form of simple key => value pairs, based on your description.
This question is quite simple but I have run into the problem a few times.
Let's say you do something like:
cars = Vehicle.find_by_num_wheels(4)
cars.each do |c|
puts "#{c.inspect}"
end
This works fine if cars is an array but fails if there is only one car in the database. Obviously I could do something like "if !cars.length.nil?" or check some other way if the cars object is an array before calling .each, but that is a bit annoying to do every time.
Is there something similar to .each that handles this check for you? Or is there an easy way to force the query result into an array regardless of the size?
You might be looking for
cars = Vehicle.find_all_by_num_wheels(4)
The dynamic find_by_ methods only return one element and you have to use find_all_by_ to return multiple.
If you always want all of the cars, you should use find_all instead:
cars = Vehicle.find_all_by_num_wheels(4)
You could also turn a single Vehicle into an array with:
cars = [cars] unless cars.respond_to?(:each)
Named scoped version for your problem
Vehicle.scoped(:conditions => { :num_wheels => 4 } ).each { |car| car.inspect }
You can do this to get arrays everytimes :
cars = Vehicle.find(:all, :conditions => {num_wheels => 4})
I don't think that you have a loop that will check if the object is an array.
Another solution could be:
for i in (1..cars.lenght)
puts cars[i].inspect
end
(haven't tested, it might break to test the lenght on a string. Let me know if it does)