Access hash by primary key - ruby rails - ruby-on-rails

I thought this could be done trivially but I am unable to do so.
My current code is:
#player_types = squad.player_types
Now I loop and lookup for the id,
params[:player_types].each do |p_type|
#player_types.find(p_type[:id])
end
Why does #player_types.find(p_type[:id]) have to execute the the select query when I look up the server logs, havent I loaded this. Is it because of the lazy evaluation and is there a way to load everything at the start and access it as an index in the hash?

The better way to use arel gem, and to select all record with specific ids is this:
ids = params[:player_types].map {|v| v[:id] }
#player_types.where(#player_types.class.arel_table[:id].in(ids))

If player_types is a table, you can directly select all of the player_types in the params[:player_types] array by passing the array to a where condition.
#player_types = PlayerType.where(id: params[:player_types])

Related

Rails 4 update_all and set value from another field

I need to do some bulk updates in some models and set value of a field as value of another field.
Right now I can do that with raw sql like this:
ActiveRecord::Base.connection.execute("UPDATE `deleted_contents` SET `deleted_contents`.`original_id` = `deleted_contents`.`id` WHERE `deleted_contents`.`original_id` is NULL")
This is working fine, however I need to do this using ActiveRecord query interface due to many reasons.
I tried:
DeletedContent.where(original_id: nil).update_all(original_id: value_of_id_column)
For value_of_id_column I tried :id, self.id, id, etc, nothing works. What should I set for value_of_id_column to get the original query generated by rails? Is this possible, or using the raw sql is the only solution?
Also I do not want to iterate over each record and update. This is not a valid solution for me:
DeletedContent.where(original_id: nil).each do |deleted_content|
update_each_record
end
I'm pretty sure you cannot obtain that query by passing a hash to update_all.
The closest to what you want to obtain would be:
DeletedContent.where(original_id: nil).update_all("original_id = id")

Parse hash for value from a table

I am writing a AWS-Federation proxy in Rails. This means I grab for some groups using net-ldap on our local ActiveDirectory and want to compare those to a list and look for matches. My NetLDAP-searchresult is this hash:
[#<Net::LDAP::Entry:0x000000048cfdd0 #myhash={:dn=>["CN=Username,OU=Support,OU=mycompany ,OU=Organisation,DC=mycompany,DC=com"], :memberof=>["CN=My AWS Groupname,CN=Receiver,CN=Users,DC=mycompany,DC=com"]}>]
Now I want to parse this hash and look for matches in a local "groups" table. It looks like that:
Name AWS-Role
My AWS-Groupname Some Group
AWS-Othergroup Some Other-Group
I have a group-model.
What is a best practices approach? I've never done something like this before. Would I use a Regex here? Do I loop the groups through all tables? What's the rails way to do this?
edited for more information
I'm going to assume a few things here, since I don't know where you get the LDAP search results from, but assuming your hash looks like this:
EDIT:
based on the additional information:
// Example
require 'net-ldap'
entry = Net::LDAP::Entry.new
entry.dn = ["CN=Username,OU=Support,OU=mycompany ,OU=Organisation,DC=mycompany,DC=com"]
entry[:memberof] =["CN=My AWS Groupname,CN=Receiver,CN=Users,DC=mycompany,DC=com"]
name = entry.memberof.first.split(',').first.gsub('CN=', '')
And assuming you have a model called Group that is mapped to this "groups" table, you can do something like this:
Group.where(name: name).any?
If you find any results, it means you have a match in the table.
But this completely depends on the table structure and hash. To properly answer your question, I'd need to see what Objects you have in Rails, and what the structure of your Hash looks like.
EDIT:
Updated my answer based on the received feedback. Use code at own risk.

Returning a hash instead of array with ActiveRecord::Base.connection

I have to use a query like this :
query = Enc.joins(:rec).group("enc.bottle").
select("enc.bottle as mode, count(rec.id) as numrec, sum(enc.value) as sumvalue")
That I use with :
#enc = ActiveRecord::Base.connection.select_all(query)
To get the data, I've to do #enc.rows.first[0] (it works)
But #enc.rows.first["mode"] doesn't work ! Because each row of #enc.rows contains array.. not a map with the name of each field.
Maybe select_all is a wrong method.
Does it exist another method to get the data with the name of field ?
Thank you
EDIT
If you can associate a model with the query, then there's no need for the generic select_all method. You can use find_by_sql like this:
Enc.find_by_sql(query).first.mode
# => testing
Note that you will no be able to see the aliases when inspecting the results, but they are there. Also, the convention is to use plural names for the tables. You might find it easier to just sticks with the defaults.

Rails: Getting column value from query

Seems like it should be able to look at a simple tutorial or find an aswer with a quick google, but I can't...
codes = PartnerCode.find_by_sql "SELECT * from partner_codes where product = 'SPANMEX' and isused = 'false' limit 1"
I want the column named code, I want just the value. Tried everything what that seems logical. Driving me nuts because everything I find shows an example without referencing the actual values returned
So what is the object returned? Array, hash, ActiveRecord? Thanks in advance.
For Rails 4+ (and a bit earlier I think), use pluck:
Partner.where(conditions).pluck :code
> ["code1", "code2", "code3"]
map is inefficient as it will select all columns first and also won't be able to optimise the query.
You need this one
Partner.where( conditions ).map(&:code)
is shorthand for
Partner.where( conditions ).map{|p| p.code}
PS
if you are often run into such case you will like this gem valium by ernie
it gives you pretty way to get values without instantiating activerecord object like
Partner.where( conditions ).value_of :code
UPDATED:
if you need access some attribute and after that update record
save instance first in some variable:
instance=Partner.where( conditions ).first
then you may access attributes like instance.code and update some attribute
instance.update_attribute || instance.update_attributes
check documentation at api.rubyonrails.org for details

Random jokes in a skit (activerecord)

I am working on populating my database with test data using populate.rake:
Repertoire.includes(:jokes).each do |r|
#jokes = r.jokes
Skit.populate 8..12 do |skit|
skit.joke_id = #jokes[rand(#jokes.count)].id
end
end
This is giving me a RuntimeError: Called id for nil.
How can I populate a skit with random jokes?
sort_by {rand} should sort your array of jokes.
Or, there is also doing an .order("rand()/random()") (depending on your db) in your Repertoire query and putting a limit on the query.
Not sure if this will fix your problem but Ruby has a rand method for arrays so you should be able to call #jokes.rand.id instead. Seems like that would simplify things and maybe even fix your error.

Resources