Incrementing database value in Rails - ruby-on-rails

In Rails, I'd like to update some database value by incrementing it.
Say, I have value 30 in a table and I'd like to add 0.5.
Here is how I've tried to accomplish it:
Record.where(:status => "somestatus").first.value.to_f += 0.5
RoR complains saying "undefined method `to_f='".
I know that I can obtain value first, calculate the result and update_attributes at the end. But what is the most efficient way to do it?

Hope the field value is of type Float, the following will do the update the value by what ever you want.
object = Record.where(:status => "somestatus").first
object.increment!(:value, 0.5)
Check here for documentation on increment! method.

Related

ruby on rails pass a value to .last()

I'm pretty new to ruby on rails, so I'm probably missing some syntax. Big picture I am trying to get the value for a specified percentile. Conceptually I am taking my table 'Scores', sorting it, getting the last 'x' values, and then taking the first value. I can't seem to figure out how to pass 'x', which is based on the length of the dataset to the chain.
def get_percentile()
record_count = Scores.count(:id)*0.05
record_threshold = record_count.round()
Score_percentile = Scores.order(:points).last(record_threshold).first().points
return Score_percentile
end
get_percentile
If I just enter .last(20) this works as I expect, so I just don't know how to pass the variable.
Thanks.
You may be passing a 0 into your .last() function with your rounding.
There are a variety of options to make sure you pass at least a 1
[record_threshold, 1].max will give you at least 1. https://apidock.com/ruby/Enumerable/max
Changing .round() to .ceil() rounds up in all instances. https://apidock.com/ruby/Float/ceil

Rails hash TypeError

I have the following hash, #example_set that I want to get and store data from.
{"Example1"=>{:campaign=>"Example1", :impressions=>12, :conversions=>1, :clicks=>14,
"Example2"=>{:campaign=>"Example2", :impressions=>4042, :conversions=>2, :clicks=>11}}
I want to do the following to combine the total conversions but am running into a TypeError: no implicit conversion of Symbol into Integer.
#totals = 0
#example_set.each do |report|
#totals += report[:conversions]
end
Ideally this would set #totals to 3
I am new to rails so any additional detail and instruction would be much appreciated (especially if there is a better way to do this.. which I assume there is)
You want to iterate over values of that map, I think.
#example_set.values.each

Storing value of calculation that query result is being ordered by with Rails

I'm new to rails but I still feel I should know the answer to this. Drawing a complete blank.
I have the following query that returns the expected results. However I want to also store the value the calculation they are being ordered by returns.
What is the best way of extracting this value.
Here is the line of code
#service = Service.order("ST_Distance(services.lon_lat, ST_GeomFromText('POINT (lat lon)', 4326))").limit(10)
As I said it returns the correct results but I'd also like to find the distance for each result
Thank you
Try this:
#services = Service.select("*, ST_Distance(services.lon_lat, ST_GeomFromText('POINT (lat lon)', 4326)) as st_distance").order("st_distance").limit(10)
the objects you get back in #services (note i changed this to the plural in keeping with convention) should have an additional method .st_distance, which is what i set the results of that function to be called with as st_distance

How to get column from active record query

1 and #2 both do not work. Active Record drives me nuts because I cam never remember when it returns an object or an array. Neither is working this time.
question = Question.select('id, question, promo_title, promo_code, group_id').where(:group_id => group_id).limit(1)
1
cookies[:question_id] = question['id']
2
cookies[:question_id] = question.id
You need to do
cookies[:question_id] = question[0].id
Your query will give you Question::ActiveRecord_Relation object. In order to get the data, you can use #each to iterate through all the records, and #[] to get any specific from the resultant collection. In your case it is holding only one record, so you can use #[] method with the argument to it as 0.
Now question[0] will give you a Question instance, now you can call the #id method on it as per the regular Rails way.

activerecord sum returns a string?

This seems very strange to me, an active record sum returns a string, not a number
basket_items.sum("price")
This seems to make it work, but i thought i may have missed something, as this seems like very strange behaviour.
basket_items.sum("price").to_i
According to the (rails 2.3.9) API:
The value is returned with the same data type of the column, 0 if there’s no row
Could your price column be a string or text?
https://github.com/rails/rails/pull/7439
There was a reason it returned a string - calling to_d on a Fixnum in Ruby 1.8 would give a NoMethodError. This is no longer the case in Ruby 1.9 so it's probably okay to change.
ActiveRecord sum:
Difference:
1) basket_items.sum("price")
It will also sum non integer also and it will return non integer type.
2) basket_items.sum("price").to_i
This above will convert into integer.
# File activerecord/lib/active_record/relation/calculations.rb, line 92
def sum(*args)
if block_given?
self.to_a.sum(*args) {|*block_args| yield(*block_args)}
else
calculate(:sum, *args)
end
end
Calculates the sum of values on a given column. The value is returned with the same data type of the column, 0 if there’s no row.
http://api.rubyonrails.org/classes/ActiveRecord/Calculations.html#method-i-sum
Github:
https://github.com/rails/rails/blob/f8f4ac91203506c94d547ee0ef530bd60faf97ed/activerecord/lib/active_record/relation/calculations.rb#L92
Also see, Advanced sum() usage in Rails.

Resources