Convert string to number in where clause - ruby-on-rails

I have the following where clause:
OnlineCourseRegistration.where(course_class_id: 6, status: "Completed")
=> #<OnlineCourseRegistration id: 142, cart_id: 150, user_id: 7069, course_class_id: 681, created_at: "2017-07-15 22:06:06", updated_at: "2017-07-20 23:59:01", exam_attempts: 1, exam_completed_at: "2017-07-20 23:57:32", evaluation_completed_at: "2017-07-20 23:59:01", status: "Completed", score: "87", add_extension: false, retest_cart_id: nil, retest_purchased_at: nil>
I would also like to add that the score would be greater than 70, so something like...
OnlineCourseRegistration.where(course_class_id: 681, status: "Completed", :score.to_i > 70).last
...but of course, this doesn't work. Is there a way to do this within the where clause?

ActiveRecord where accepts string as query constructor
OnlineCourseRegistration.where("course_class_id = ? AND status = ? AND score > ?", 681, "Completed", 70).last

If you prefer not to use raw SQL you can use the Arel methods, for example:
OnlineCourseRegistration.where(course_class_id: 681, status: "Completed").where(OnlineCourseRegistration.arel_table[:score].gt(70)).last

For posterity I wanted to add these cast solutions as an answer also:
where("score::int >= ?", 80) # PostgreSQL-specific casting syntax
where("cast(score as int) >= ?", 80) # Standard SQL type cast

Related

How to use the PostgreSQL JSON array query ActiveRecord::Relation in Ruby on Rails

I want to query ActiveRecord::Relation with 51 fields.
the data structure is like this:
matings: {"ids"=>[50, 51, 64]}
or
matings: {"ids"=>51}
If I do:
MouseColony.where("CAST(matings AS TEXT) LIKE ?", "%51%")
=>#<ActiveRecord::Relation [
#<MouseColony id: 604, animal_no: "a0008", animal_desc: "", gender: "M♂", source: "外购", animal_status: "配对", cage_id: nil, generation: 0, birth_date: "2018-12-25", weaning_date: "2019-01-15", disable_date: nil, received_date: "2019-03-20", created_at: "2019-06-03 02:45:03", updated_at: "2019-06-03 03:14:37", user_id: 1, strain_id: 1, mating_id: 64, litter_id: nil, purchase_mouse_number: "17203", age: 223, mating_quantity: 3, matings: {"ids"=>[50, 51, 64]}, genotype_id: 10, experiment_id: nil, experiment_date: nil, age_weeks: 32>,
#<MouseColony id: 624, animal_no: "a0028", animal_desc: "", gender: "F♀", source: "外购", animal_status: "配对", cage_id: nil, generation: 0, birth_date: "2018-12-25", weaning_date: "2019-01-15", disable_date: nil, received_date: "2019-03-20", created_at: "2019-06-03 02:50:07", updated_at: "2019-06-03 03:09:11", user_id: 1, strain_id: 1, mating_id: 51, litter_id: nil, purchase_mouse_number: "17138", age: 223, mating_quantity: 5, matings: {"ids"=>51}, genotype_id: 9, experiment_id: nil, experiment_date: nil, age_weeks: 32>
]>
I tried to use MouseColony.where("CAST(matings ->> 'ids' AS TEXT) LIKE ?", "%51%") or using MouseColony.where("matings ->> 'ids' = ?", "51"), but the result is such a MouseColony Load (1.0ms) SELECT "mouse_colonies".* FROM "mouse_colonies" WHERE (CAST(matings ->> 'ids' AS TEXT) LIKE '%51%') LIMIT $1 [["LIMIT", 11]]
=> #<ActiveRecord::Relation []>
I've also tried to use this:
MouseColony.where("matings #>> '{ids}' = ?", "51")
But still can't find any data.
I think my problem might be here:
My models: mouse_colony.rb
store :matings, :accessors => [:ids], coder: JSON
and I storage record like this:
#mouse_colony.matings[:ids] = [50, 51, 64]`` #mouse_colony.save
You can try using the "contains" operator #>:
MouseColony.where("matings->'ids' #> '?'", 51)
You should be able to use the LIKE operator like this:
MouseColony.where("matings::json->>'ids' LIKE ?", "%51%")

Spree: Return only Orders with Line Items in them

I'm having trouble setting up the controller in a spree app so it only returns orders with line_items in them.
<Spree::Order id: 1057, number: "R498797188", item_total: #<BigDecimal:7f90c2acf4b8,'0.999E1',18(18)>, total: #<BigDecimal:7f90c2acf1e8,'0.1098E1',18(18)>, state: "payment", adjustment_total: #<BigDecimal:7f90c2ace770,'0.0',9(18)>, user_id: nil, completed_at: nil, bill_address_id: 1814, ship_address_id: 1815, payment_total: #<BigDecimal:7f90c2acc358,'0.0',9(18)>, shipping_method_id: nil, shipment_state: nil, payment_state: nil, email: nil, special_instructions: nil, created_at: "2015-09-10 22:31:23", updated_at: "2015-09-10 22:33:03", currency: "USD", last_ip_address: "127.0.0.1", created_by_id: nil, shipment_total: #<BigDecimal:7f90c4b721e8,'0.199E1',18(18)>, additional_tax_total: #<BigDecimal:7f90c4b71fb8,'0.0',9(18)>, promo_total: #<BigDecimal:7f90c4b71e78,'0.0',9(18)>, channel: "spree", included_tax_total: #<BigDecimal:7f90c4b71798,'0.0',9(18)>, item_count: 1, approver_id: nil, approved_at: nil, confirmation_delivered: false, considered_risky: false>
There is a record on Spree::Order called item_count that needs to be > 0, but I don't know what the syntax needs to be in the controller?
#orders = Spree::Order.all.where(:item_count > 0) #this returns the following error: comparison of Symbol with 0 failed
This seems simple, but any help would be greatly appreciated! Thanks!
You can use symbol to check for absolute value, like where(item_count: 0), but not for comparison like that.
Inside where, when you are using symbols, you are actually working on a Hash object.
.where(item_count: 0)= .where({item_count: 0})
and to work with a hash, you should have key-value pair like above, not comparison. {:item_count > 0} is an invalid hash syntax.
For comparison in your case, use string:
#orders = Spree::Order.where('item_count > 0').all
Also, you should use .all, at the end of relation, if all needed. all returns the scope object and is usually meant to fetch all the records matching the query before it.

How to get the data using find_by Or where in rails?

Truck
id: 1,
vehicle_registration_number: "TN38CC6077",
chassis_number: "12345",
created_at: "2016-09-06 05:39:19",
updated_at: "2016-09-06 05:39:19",
company_truck_type_id: 1,
location_id: 492,
available_date: ["2016-09-10",
"2016-09-20"],
booked_status: "Available",
active: true,
manager_id: 3,
loading_supervisor_id: 3,
transport_supervisor_id: 3,
user_id: 3,
status: "just_in",
price: #<BigDecimal:afae0204,'0.109E5',9(18)>,
source_id: 492,
destination_id: 3,
notes: ["HelloWorld"]
This is my data in a table. From Here I have use available_date to find a current data,but it can't working. How can I get based on current date?
#truck[0].where(available_date:["2016-09-10"]["2016-09-20"])
It's not working. I want to check if the current date is between the available_date or not?
you can do something like below:
Truck.where(available_date: (Time.now.midnight - 1.day)..Time.now.midnight)
Hope that helps you.
Try this code snippets ;
def current_date_is_available?(available_date)
current_date = Date.parse(Time.now.to_s)
Date.parse(available_date.first) < current_date && current_date < Date.parse(available_date.second)
end
in controller ;
if current_date_is_available?(#truck[0].available_date)
# do whatever you want
end

Rails how to calculate multiple sums from one query data

With the following two models, Company and Response, I am making a query of the total responses per company like this:
#allResponses = Company.find(current_user_company_id).responses
this gives me data like this:
[#<Response id: 1, company_id: 1, created_at: "2013-04-24 02:36:54", feedback_score: 10, feedback_explanation: "I really like the way you guys do xyz.", additional_data: "", updated_at: "2013-04-24 02:36:54">, #<Response id: 2, company_id: 1, created_at: "2013-04-25 03:51:07", feedback_score: 5, feedback_explanation: "customer service is spotty.", additional_data: "", updated_at: "2013-04-25 03:51:07">, #<Response id: 3, company_id: 1, created_at: "2013-04-25 03:52:04", feedback_score: 7, feedback_explanation: "You've got potential.", additional_data: "", updated_at: "2013-04-25 03:52:04">, #<Response id: 4, company_id: 1, created_at: "2013-04-25 03:52:18", feedback_score: 9, feedback_explanation: "Almost perfect.", additional_data: "", updated_at: "2013-04-25 03:52:18">]
I want to get the following two variables out of this data:
#sumOfHighScores = some.thing.here #sum of feedback_scores that are greater than 8
#sumOfLowScores = some.thing.here.too #sum of feedback_scores that are less than 7
You can try this,
#sumOfHighScores = #allResponses.select{ |response| response.feedback_score > 8 }.map(&:feedback_score).sum
#sumOfLowScores = #allResponses.select{ |response| response.feedback_score < 7 }.map(&:feedback_score).sum
Try this..
#sumOfHighScores = #allResponses.select{ |response| response.feedback_score > 8 }.sum
#sumOfLowScores = #allResponses.select{ |response| response.feedback_score < 7 }.sum
I will perform the entire calculation in the database.
company = Company.find(current_user_company_id)
totals = company.responses.sum(
:feedback_score,
:group => "CASE WHEN feedback_score < 7 THEN 'low' ELSE 'high' END")
low, high = (totals['low'] || 0), (totals['high'] || 0 )

Unexpected behaviour of array.count in ruby

Hi i am using Rails3 when i puts array of subscribers like this
#subscribers = User.all
and puts it.gives me this array
[#<User id: 62, is_activated: true, subscriber: "TEST_DB2", ports_order: 100, created_at: "2012-05-21 14:47:48">, #<User id: 66, is_activated: true, subscriber: "JOHI", ports_order: 100, created_at: "2012-05-22 12:06:19">, #<User id: 68, is_activated: true, subscriber: "ALI-NAQWI", ports_order: 100, created_at: "2012-05-24 11:01:22">]
And when i give command
#subscribers.count #it give me 0 count
Why?????????
Try length instead, it can be a bug in AREL :)
That he is trying to lazy do something. He is giving back proxy object so it can be a problem there. Length will always work on your result value ~ array.

Resources