How to update jsonb object using update_all? - ruby-on-rails

I have an array of students with a jsonb field attendance array. I wanted to add a new object into it for all volunteers. How can i do this. I'm using ruby on rails and postgres.
I tried jsonb updateall according to the documentation. And tried this
Item.where(id: items).
update_all(
"properties = jsonb_set(properties, '{price}', to_json(#{unique_price}::int)::jsonb)"
)

Related

How to get postgressql database native datatypes in rails server console

I having a rails application, with database as postgressql.
I am having a requirement, where i need to share the datatype of the field as per postgres sql database terminology for the sake of API integration.
Is there any way or method by which we can get the native data types of PostgreSQL database of my application.
i tried the below commands in rails console
fields_array ["abc","cde","mno","pqr","stv" ,,,,,,, so on]
fields_array.each do |field_name|
p field_type = User.type_for_attribute(field_name).type
p sql_type = User.type_for_attribute(field_name).sql_type ## not working###
end
But i am getting the datatype as per rails. i need the datatype of the column and size as per the postgressql native datatype. as there are hundredes of fields, i want to loop through them, and get the datatype of each field.
sql_type = User.columns.map{ |column| column.sql_type if c.name == field_name }.compact.first
You can get all the column sql_types in the User.columns collection. You iterate with map over them and return the column.sql_type if its name is equal to the field_name. This returns an array with many nils and one sql_type string if the field_name exists. .compact then just clears the array from nils and returns a single element array. Now you can call .first to get the plain string.

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

Ruby Rails, JSON - match results if value exists

The set up is ruby on rails, in a postgres database. The table is called line_sources and a JSON column is called names. I want to return all rows where the names column contains a value called name1. I'm trying this but it fails:
LineSource.where("names ->> '%' = 'name1'")
Perhaps jsonb can be used for that?

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