Get keys of activerecord - ruby-on-rails

I've got an active record to which I want to collect its keys in a seperate array
So if my #item.first has
item.a = 1
item.b = 2
item.c = 3
I want to collect an array like [a => 1, b => 2, c => 3].
Is there a way to do this?

This can be done with attributes:
#item.first.attributes
And to select specific attributes you can filter with select as:
#item.first.attributes.select { |key| ['a', 'b', 'c'].include?(key) }

yes you can do it using as_json read this http://api.rubyonrails.org/classes/ActiveModel/Serializers/JSON.html#method-i-as_json

Related

Search by array of values in .select query method

I'm having this type of search:
values = ModelName.find(:all, :conditions => ['attr_id IN (SELECT attr_id FROM srv_type_attr WHERE id IN (?))', serv_objt_attr.collect(&:stya_id)])
Witch returns me an array of needed values:
[33458, 33438]
Next i need to check if record exists with select:
serv_objt_attr.select {|array| array.stya_id == values.collect(&:attr_id).uniq}
This is an example what i'm thinking off.
So how to do it with select, so he would walk through all values witch i'm getting from values.
I know that i could to something like
values.collect(&:attr_id).uniq do |val|
serv_objt_attr.select {|array| array.stya_id == val}
end
But i do not thing that this is a good option.
Ruby 1.8.7
Rails 2.3.4
This is a good case for the set intersection operator:
values = ModelName.find(:all, :conditions => ['attr_id IN (SELECT attr_id FROM srv_type_attr WHERE id IN (?))', serv_objt_attr.collect(&:stya_id)])
values & Set.new(serv_objt_attr.map(&:stya_id)
Here's what the & does:
>> values = [1,2,3]
=> [1, 2, 3]
>> other_array = [1,5,9,3]
=> [1, 5, 9, 3]
>> values & other_array
=> [1, 3]

How do I check if my hash has a key from an array of strings?

With Ruby, if I have a hash, what is the fastest way to check if it has a key from an array of strings? So I could do this
has_key = false
arr_of_strings.each do |str|
if my_hash.has_key?(str)
has_key = true
break
end
end
But taht seems like way too many lines of code for such a simple inquiry.
As simple as this:
arr_of_strings.any? {|s| my_hash.key?(s) }
Or, to get bonus points for clever-yet-less-readable code:
arr_of_strings.any?(&my_hash.method(:key?)) # => true
To see if the array and the keys have any in common, you can use set intersection:
(arr & hash.keys).any?
strings = ['a', 'b', 'c']
hash = {:a => 'apple', :b => 'bob', :d => 'thing'}
has_key = hash.keys.map(&:to_s) & strings # ['a', 'b']
has_key.any? # true
a one-liner that's similar, hash.keys.detect { |key| strings.include?(key.to_s) }.nil?

How do I find the first elelment in my Ruby array matching certain criteria?

I’m using Rails 4.2.7. I want to find the first item in my array of objects whose fields match certain criteria. So I wrote this lengthy loop …
result = nil
results.each do |r|
if r.valid?
result = r
break
end
end
My question is, is there a shorter way to do this?
Yup there is:
result = results.find(&:valid?)
https://ruby-doc.org/core-2.2.3/Enumerable.html#method-i-find
Thanks to Rashmirathi for the ampersand + colon shortcut!
You can try to do that using Array method select
results = [{id: 1, valid: true}, {id: 2, valid: false}, {id:3, valid: true}]
result = results.select { |item| item[:valid] == true}.first
You can find more at array documenation: https://ruby-doc.org/core-2.2.0/Array.html#method-i-select

How to use has_key with a collection?

I Have an collection:
[a, b, c]
and i want verify if a hash contains some key of this collection
I try:
col = [a, b, c]
my_hash = {c => 1, f => 2, h => 3}
my_hash.has_key? col
=> false
but not work.
Can anybody help me?
Thanks.
1. Iterate over col and check each.
No explanation required.
2. Use existing library functionality to do the same:
keys = [:a, :b, :c]
h = { c: 1, f: 2, h: 3 }
h.any? { |key, val| keys.include? key }
=> true
3. Set math:
h.keys & keys
=> [:c]
Then wrap it up to return true/false depending on which way you want things to read.
Try this:
my_hash.keys & col
# => [c]
& intersects the list of keys with the col array, returning only item in col which appear as keys in my_hash.
Another option - values_at:
my_hash.values_at(*col).compact
# => [1]
But you can do:
my_hash.any? { |key,_| col.include?(key) }
Read it like - Any key from my_hash included in col array.

Ruby mixed array to nested hash

I have a Ruby array whose elements alternate between Strings and Hashes. For example-
["1234", Hash#1, "5678", Hash#2]
I would like to create a nested hash structure from this. So,
hash["1234"]["key in hash#1"] = value
hash["5678"]["key in hash#2"] = value
Does anyone have/now a nice way of doing this? Thank you.
Simply use
hsh = Hash[*arr] #suppose arr is the array you have
It will slice 2 at a time and convert into hash.
I don't think there is a method on array to do this directly. The following code works and is quite easy to read.
hsh = {}
ary.each_slice(2) do |a, b|
hsh[a] = b
end
# Now `hsh` is as you want it to be
Guessing at what you want, since "key in hash#1" is not clear at all, nor have you defined what hash or value should be:
value = 42
h1 = {a:1}
h2 = {b:2}
a = ["1234",h1,"5678",h2]
a.each_slice(2).each{ |str,h| h[str] = value }
p h1, #=> {:a=>1, "1234"=>42}
h2 #=> {:b=>2, "5678"=>42}
Alternatively, perhaps you mean this:
h1 = {a:1}
h2 = {b:2}
a = ["1234",h1,"5678",h2]
hash = Hash[ a.each_slice(2).to_a ]
p hash #=> {"1234"=>{:a=>1}, "5678"=>{:b=>2}}
p hash["1234"][:a] #=> 1
let's guess, using facets just for fun:
require 'facets'
xs = ["1234", {:a => 1, :b => 2}, "5678", {:c => 3}]
xs.each_slice(2).mash.to_h
#=> {"1234"=>{:a=>1, :b=>2}, "5678"=>{:c=>3}}

Resources