update columns with update_all & another column but convert values to array - ruby-on-rails

I have column_1(string) and i created column_2(string) and seriallized column_2 as array
class Model < ActiveRecord::Base
serialize :column_2, Array
...
And i need to update column_2 with column_1 values, like this:
Model.update_all('column_2 = column_1')
But because i use serrialize as array for column_2, i need to save all values(strings) from column_1 as array
UPD.
I tried .update_all('column_2 = (array[column_1]), but in this case, anyway when i call column_2 i get it as string:
"{\"value\"}"

Yes, it is possible using below query Use array_to_json to convert to array correctly
Model.update_all("column_2 = (array_to_json(array[column_1]))")
Incorrect: - I am not sure if directly using the SQL to convert the column data would work here. Rails has inbuilt serialize method that converts the data before pushing to sql. So the conversion of string to array is not possible at the sql level. You would need to resort to iterate over the records and update each record like below:-
model_instance.update('column_2 = ?', [column_1])

Related

Updating the column of object in rails object by its position in the array

I have an array of objects in Rails for some table. I want to update its order field by the position of that object in the array with a single Active Record Query. How can I do that?
I have tried the update_all.(:"order" => ?) but couldn't get the object which is updating in update_all.
Suppose #user (only a reference you can use your corresponding object) is the array of objects (Activerecord) , then to update order field of all users in the array, you would have to run the following query
#user.update_all(order_field: value)
Suppose you have an array of posts, then you can do something like the following
posts.each_with_index do |post, index|
post.update_attributes order: index
end
This will execute a single query for each post. If you want a single query to update all the posts in the array, that is a lot harder to achieve. Options I can think of:
bulk updating
using a stored procedure

How do I extract a field from an array of my models in order to form a single query?

I’m using Rails 4.2.7. I have an array of my model objects and currently I’m iterating through that array to find matching entries in the database based on a field my each object …
my_object_times.each_with_index do |my_object_time, index|
found_my_object_time = MyObjectTime.find_by_my_object_id_and_overall_rank(my_object_id, my_object_time.overall_rank)
My question is, how can I rewrite the above to run one query instead of N queries, if N is the size of the array. What I wanted was to force my underlying database (PostGres 9.5) to do a “IF VALUE IN (…)” type of query but I’m not sure how to extract all the attributes from my array and then pass them in appropriately to a query.
I would do something like this:
found_my_object_times = MyObjectTime.where(
object_id: my_object_id,
overall_rank: my_object_times.map(&:overall_rank)
)

What is simplest way to convert :pluck or :collect results to array of strings in Rails?

I have a model called Record and belongs Product model,
the price column type is hexadecimal. Rails already convert it to string in view. But I wanna get them in my console queries.
Example code for pluck:
Product.first.records.pluck(:price)
This query displays the values in array as hexadecimal. There is a method called to_sentences for pluck values but its not enough for my case.
The problem is same in collect method:
Product.first.records.collect(&:price)
What is the pluck query to display my hexadecimal data as array of strings like:
["45,46","75,42"]
Product.first.records.pluck(:price).map(&:to_s)
please try this:
Product.first.records.pluck(:price).join(',')

how to get 2-d hash as an output from hstore column?

In rails app I try to store 2-d hash in postgreSql hstore column, but for output I get something like
{"6/5"=>"{\"color\"=>\"white\"}", "8/1"=>"{\"color\"=>\"white\"}", "8/2"=>"{\"color\"=>\"white\"}", "8/3"=>"{\"color\"=>\"white\"}"}.
How can I get 2-d hash as output or maybe you can give some advice for how to parse it?.
If you need to convert this into hash here is how you could it do:
str = {"6/5"=>"{\"color\"=>\"white\"}", "8/1"=>"{\"color\"=>\"white\"}", "8/2"=>"{\"color\"=>\"white\"}", "8/3"=>"{\"color\"=>\"white\"}"}
p str.each_with_object({}){|(k,v),h| h[k] = eval(v)}
Result
{"6/5"=>{"color"=>"white"}, "8/1"=>{"color"=>"white"}, "8/2"=>{"color"=>"white"}, "8/3"=>{"color"=>"white"}}
To store a hash in sql database, you can use a string column and add this line to the model:
serialize :my_hash_thingy
It should handle every serialization / deserialization in the background, and you will have tha hash normally every time you use it.

Modifying the returned value of find_by_sql

So I am pulling my hair over this issue / gotcha. Basically I used find_by_sql to fetch data from my database. I did this because the query has lots of columns and table joins and I think using ActiveRecord and associations will slow it down.
I managed to pull the data and now I wanted to modify returned values. I did this by looping through the result ,for example.
a = Project.find_by_sql("SELECT mycolumn, mycolumn2 FROM my_table").each do |project|
project['mycolumn'] = project['mycolumn'].split('_').first
end
What I found out is that project['mycolumn'] was not changed at all.
So my question:
Does find_by_sql return an array Hashes?
Is it possible to modify the value of one of the attributes of hash as stated above?
Here is the code : http://pastie.org/4213454 . If you can have a look at summarize_roles2() that's where the action is taking place.
Thank you. Im using Rails 2.1.1 and Ruby 1.8. I can't really upgrade because of legacy codes.
Just change the method above to access the values, print value of project and you can clearly check the object property.
The results will be returned as an array with columns requested encapsulated as attributes of the model you call this method from.If you call Product.find_by_sql then the results will be returned in a Product object with the attributes you specified in the SQL query.
If you call a complicated SQL query which spans multiple tables the columns specified by the SELECT will be attributes of the model, whether or not they are columns of the corresponding table.
Post.find_by_sql "SELECT p.title, c.author FROM posts p, comments c WHERE p.id = c.post_id"
> [#<Post:0x36bff9c #attributes={"title"=>"Ruby Meetup", "first_name"=>"Quentin"}>, ...]
Source: http://api.rubyonrails.org/v2.3.8/
Have you tried
a = Project.find_by_sql("SELECT mycolumn, mycolumn2 FROM my_table").each do |project|
project['mycolumn'] = project['mycolumn'].split('_').first
project.save
end

Resources