I'm trying to get a a bidimensional hash from a activerecord group request like this.
MachineFailure.group("machine.key", "failure.name").sum("timestampdiff(hour, machine_failures.created_at, closed_at)")
this returns me a hash like:
{["R01", "Corrective Maintenance"]=>3, ["R01", "Auto reboot"]=>8}
when I actually need something like this:
{"R01" => {"Corrective Maintentance" => 3, "Auto reboot" => 8}}
thx
This answer is exactly what you need.
In short, you need to map the hash that is returned after the call to the database.
Related
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'm trying to query an array of signups. Each Signup has a field on it twitter.
The field is an array and at present will only have two items, but can also only have one. The three possible outputs from calling Signup.twitter are:
Signup.twitter => ["No Twitter", "randomhandle"]
Signup.twitter => ["No Twitter"]
Signup.twitter => ["randomhandle"]
I'm trying to use a .where query to only return me handles that have a randomhandle in. If they return ["No Twitter", "randomhandle"] I still want that record to be returned though.
Any help must appreciated,
Thanks.
Try array search methods, like find_all (select is the same) or reject (http://ruby-doc.org/core-2.2.0/Enumerable.html#method-i-find_all)
Absolutely agree with the previous answer, but I would do it in 'positive' way, rather than 'negative' so as to keep it clear:
Signup.all.find_all do |signup|
# Use Array.wrap or protect it from `undefined method for nil class`
"randomhandle".in? Array.wrap(signup.twitter)
end
Ultimately, you can do whatever you want.
In case if the twitter field is association you can use where directly:
Signup.where(twitter: Twitter.where(name: "randomhandle"))
Check http://guides.rubyonrails.org/active_record_querying.html
This should work:
only_twitter_users = Signup.all.reject do |signup|
signup.twitter == ["No Twitter"]
end
I think the best way for me to explain this question is with example. Here is a simple method with a hash:
def getValues(table)
allColumns = {
'User' => ['first_name', 'last_name'],
'Vehicle' => ['make', 'model', 'id'],
}
end
I am trying to pass in the table and based on that table return a range of values. I would like to know what would be (performance-wise) the best way to accomplish this. Is it using a switch statement, if/else, some sort of loop? If you come up with an answer, please be as kind to include an example so that I may understand better.
I suggest you to rename the parameter first, maybe to table_name or something more descriptive.
Second it is kind of a convention in ruby to use method names separated by _, and avoid using camelCase as another languages.
Third, i would put the list on a constant variable or something, and just reference it inside the method.
Then you can look up the values of some hash based on a key just by using hash[key].
LIST = {
'User' => ['first_name', 'last_name'],
'Vehicle' => ['make', 'model', 'id'],
}
def get_values(table_name)
LIST[table_name]
end
Hash lookup by key is probably one of the most performant operations you could do with a collection, so there is no need to worry about it.
Foo.where(:some_id => 1).update_all(:some_columnn => "1")
Is this the right way to update Foo? I don't want to do a find and update the object.
As of Rails 4, the conditions are no longer supplied on the update_all method, but are instead specified on the preceding collection. For example,
# updates everything, as usual
Foo.update_all(some_column: '1')
# update only the specified rows
Foo.where(some_id: 1).update_all(some_column: '1')
Yes it is the right way, but remember, no callbacks or validations will be executed.
BTW, update_all accepts conditions also. Like this
Foo.update_all({:some_columnn => "1"}, {:some_id => 1})
It is the right approach if you don't want to instantiate an object, but keep in mind that this also means it won't perform any of your models validations or callbacks - it goes straight to a SQL update command.
Further information
You can use conditions,according to the api of update_all
update_all(updates, conditions = nil, options = {})
So you can do:
Foo.update_all(:some_column => '1', :some_id => 1)
Is there a shorter way to write this ?
Job.all(:conditions => "job_source_id=1")
A little shorter and more readable:
Job.where :job_source_id => 1
Use the Dynamic Finders
http://guides.rubyonrails.org/active_record_querying.html#dynamic-finders
Job.find_by_source_id(1)
I usually like to use scopes for this kind of thing like so:
# in the model
scope :from_sales, :conditions => { :job_source_id => 1 }
Then, from anywhere, I can just call:
Job.from_sales.all
This lets me express myself in my problem domain instead of sql.