Remove group_by field from final result rails - ruby-on-rails

I am using rails 5.2.0.
I have a City model in which id is a Primary key and name represents name of city.
I am using group_by to achieve something like this:
Expected Output:
{10571=>"Μorocco Town", 17741=> "S-HERTOGENBOSCH"}
I am trying something like this:
City.all.select('name', 'id').group_by(&:id)
The result I am getting is:
10571=>[#<City id: 10571, name: "Μorocco Town">], 17741=>[#<City id: 17741, name: "S-HERTOGENBOSCH">]}
The key part is correct.
I need to get rid of the id field coming in the hash value and also, a single hash value instead of an array with name as key.
Any suggestions?
Using group_by is not mandatory. Any other inbuilt functions will also work.

Pluck is your friend...
City.pluck(:id, :name).to_h

Related

Rails how to query a hash in a where clause

Is there a way with active record sql server adapter to query a hash field? I have a field called properties that is stored like this:
--- !ruby/hash:ActiveSupport::HashWithIndifferentAccess
summary: There is a problem
optional_information: Help!!
location: '28288'
reported_phone: "(555) 555-0352"
reported_email: person#email.com
affected_person_id: '1234'
affected_person_name: 'Tester'
affected_person_phone: '(555) 555-0352'
affected_person_email: person#email.com
I want to set up a query so that I pass a param through called filter and query either the summary field of the hash. Is this possible?
Trying to do somethings like this:
#requests = current_user.requests.where("properties->>'summary' = ?", '%#{params[:filter]}%') if params[:filter].present?
UPDATE: Per the advice below I changed the model to serialize the field as JSON. I also ran a migration to change the DB field type to JSON. Here is what the field looks like now. Still trying to figure out how to access and query the individual values.
{"summary":"Need bed raised","optional_information":"too low","location":"26679","reported_phone":"(555) 334-1324","reported_email":"mail#mail.com","affected_person_id":"1231232","affected_person_name":"testuserJ ","affected_person_phone":"(555) 334-1324","affected_person_email":"mail#mail.com"}

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")

How do you access an object's (ActiveRecord::Relation) value by key in Ruby on Rails?

tl;dr How do I get the corresponding value with the key of an object?
I'm confused why
Atag.where(tag:'brand') gives me what I would call an object for lack of a better term: #<ActiveRecord::Relation [#<Atag id: 1, tag: "brand", created_at: "2015-01-31 04:29:20", updated_at: "2015-01-31 04:29:20">]>
But I'm having the basic difficult of accessing the corresponding value for the key :id.
Atag.where(tag:'brand').id and Atag.where(tag:'brand')[:id] and Atag.where(tag:'brand')(:id) all throw errors, while in this case I'm just trying to have the integer 1 returned.
I seem to be unable to ruby, nor find a succinct answer to this basic question with my google searching skills (or lack there of).
Thanks
From great documentation at the Odin Project.
The key thing to note is that #find returns the actual record while #where returns an ActiveRecord::Relation which basically acts like an array.
So if you're using #where to find a single record, you still need to remember to go into that "array" and grab the first record, e.g. User.where(:email => "foo#bar.com")[0] or User.where(:email => "foo#bar.com").first.
This gets me all the time...
Get the id of your tag = 'brand' with following query:
Atag.find_by(tag:'brand').id
Check following variations:
Atag.find(1)
#gives you the object with the Atag id = 1
Atag.find(100) #let's say this record does not exist then you will
get ActiveRecord::RecordNotFound exception.
Better option :
Atag.where(id: 1)
#this returns you a relation and it's true you are trying to access
only a single object.
Hence, you just need to modify it to :
Atag.where(id: 1).first
#Above one will give you an object of Atag not an association result.
# to verfiy you can execute, Atag.where(id: 1).first.class
Atag.where(id: 999).first
# In this case if there is no record found with id = 999, then it'll
return nil which can be easily handled than an exception found
while using find method.
Get the same flavor using the dynamic finders.
Atag.find_by(id: 1) #gives the Atag with id 1
Atag.find_by_id(1). # same as above.
Atag.find_by(id: 999) #if not found then simply returns nil.
Atag.find_by(name: 'ruby') #return Atag object with name: 'ruby'
Atag.find_by_name('ruby') #same as above.
Yep, looks like you figured it out. For reference, you can use Atag.where(tag:'brand').first to get the first result, and Atag.where(tag:'brand').to_a to get an array of all the matching results.
where return instance of ActiveRecord::Relation which can be treated like an array with records as its members. Even if the result is single it should be accessed like a member of array with single element
Atag.where(tag: 'brand')
returns the array of results and to access id we should get the record from the array first i.e.
Atag.where(tag: 'brand')[0].id
In order to get id of all the matching records we need to use pluck with where. pluck returns an array of attribute that is plucked.
Atag.where(tag: 'brand').pluck(:id)
This would return an array of id from the collection returned by where only.
The find_by method finds the first record matching some conditions. Since find_by returns the record (not an array) , we can do:
Atag.find_by(tag: 'brand').id
PS: No one had mentioned pluck that's why I wrote this answer. Hope its helpful.

Ruby on Rails: Saving query string parameter value to database

I search google for this question but i did not find any solution for
that.
I want to save parameter value to database. this parameter send by url.
for example:
http://simple-beach-416.heroku.com/code/restserver?fname=cv
I want to save fname value(here "cv") to database.
how can i do that?
Make a model for it? This is very vague... but define a model called Fname and give it the attribute "value"
Then...
Fname.create(:value => params[:fname])
I think this is where you're going, yeah?

mongoid update_attributes changing datatypes

Im creating a simple rails app to modify data in an existing mongo database. I'm using mongoid for the interaction and can read/destroy objects just fine.
The problem comes is my mongo document has a 'node' which is a bunch of key value pairs with vary depending on the record. When i load the record like so:
MongoObject.find(BSON::ObjectId('ABC1234567890'))
=> #<MongoObject _id: ABC1234567890, node: {"totallogins"=>11, "id"=>"logIns"}>
I'm using a standard rails form to update the values so the post data looks like:
{"commit"=>"Edit", "utf8"=>"✓", "id"=>"ABC1234567890", "mongo_object"=>{"node"=>{"totallogins"=>"12", "id"=>"logIns"}}
If i then do:
#mongo_object.update_attributes(params[:mongo_object])
This works but changes the datatype of "totallogins" from an int to a string because the post data is a string.
Now active record deals with this itself but i need a solution that will work with mongoid.
Any ideas how i can do this?
Thanks. Unfortunately i can't as the fields for node are totally dynamic so i can't define them. I've come up with the following solution but its a tad ugly:
#mongo_object.node.each do |k,v|
new_value = params[:mongo_object][:node][k.to_sym]
new_value = new_value.to_i if v.class == Fixnum
#mongo_object.node[k] = new_value
end
#mongo_object.save
If you make the node an embedded_document, then you can explicitly set the field types when you declare them.
class Node
include Mongoid::Document
embedded_in :mongo_object
field :totallogins, type: Integer
...
end
http://mongoid.org/docs/documents/ mentions how to deal with types; perhaps make sure your type is an Integer?

Resources