I have a rails app (postgres + postGIS) with a post model with a rating column (integer). If I go into the console and do:
Post.order("rating DESC").map(&:id)
=> [9, 15, 19, 6, 17, 5, 4, 16, 1, 3, 13, 20, 14, 10, 8, 12, 7, 2, 18, 11]
yet if I try to cycle through those one at a time with limit and offset, I get bizarre results.
Post.order("rating DESC").limit(1).offset(0)
=> [#<Post id: 5, body: "Hi", rating: 4, location: #<RGeo::Geographic::SphericalPointImpl:0x81bb34c0 "POINT (-118.495 34.017)">, user_id: 8, created_at: "2012-07-25 22:43:41", updated_at: "2012-07-25 22:43:41">]
Why is that post #5? It should be #9. Anyway then it gets even more wacko when I apply an offset.
>Post.order("rating DESC").limit(1).offset(1)
=> [#<Post id: 5, body: "Hi", rating: 4, location: #<RGeo::Geographic::SphericalPointImpl:0x81bb34c0 "POINT (-118.495 34.017)">, user_id: 8, created_at: "2012-07-25 22:43:41", updated_at: "2012-07-25 22:43:41">]
>Post.order("rating DESC").limit(1).offset(2)
=> [#<Post id: 5, body: "Hi", rating: 4, location: #<RGeo::Geographic::SphericalPointImpl:0x81bb34c0 "POINT (-118.495 34.017)">, user_id: 8, created_at: "2012-07-25 22:43:41", updated_at: "2012-07-25 22:43:41">]
>Post.order("rating DESC").limit(1).offset(3)
=> [#<Post id: 5, body: "Hi", rating: 4, location: #<RGeo::Geographic::SphericalPointImpl:0x81bb34c0 "POINT (-118.495 34.017)">, user_id: 8, created_at: "2012-07-25 22:43:41", updated_at: "2012-07-25 22:43:41">]
>Post.order("rating DESC").limit(1).offset(4)
=> [#<Post id: 15, body: "I luv coffee", rating: 4, flagged: 0, location: #<RGeo::Geographic::SphericalPointImpl:0x82260df4 "POINT (-118.495 34.017)">, user_id: 1, created_at: "2012-07-25 22:43:41", updated_at: "2012-07-25 22:43:41">]
Do you notice that rating is 4 for the only results that you're showing? You're sorting on rating with no secondary sort key so there's no guarantee about what order ties will appear in or even that the ties will be ordered the same way in two different calls.
Try adding a tie breaker to your order:
Post.order('rating DESC, id')
and then include the rating in what you're looking at:
Post.order('rating desc, id').select('id, rating').map { |p| [ p.id, p.rating ] }
Post.order('rating desc, id').select('id, rating').limit(1).offset(3).map { |p| [ p.id, p.rating ] }
#...
That should give you sensible and consistent results.
Related
Ruby on Rails 4
I am trying to join an Array of questions and a grouped by hash together by the question's id.
The Hash is grouped by the question_id attribute of its records from Answers.
The Array has all the Questions, and index is id.
I was trying to put them into an array, #pdf. The question first then the answers by the enumerator index. But it is behaving odd.
#pdf = []
#test = Test.find(params[:id])
#test_questions = #test.questions
answers = Answer.find(:all)
#all_answers = answers.group_by(&:question_id)
#test_questions.each do |q|
#pdf << q
#pdf << #all_answers.select { |i| i == q }
end
The log shows this:
=> [#<Question id: 1, content: "How did the chicken cross the road?", question_type: "MC", category: "ip_voice", product_id: 8, active: true, created_at: "2014-05-07 17:10:14", updated_at: "2014-05-07 17:10:14", user_id: 1>, {}, #<Question id: 2, content: "Is this working?", question_type: "TF", category: "ip_voice", product_id: 6, active: true, created_at: "2014-05-13 16:10:53", updated_at: "2014-05-13 16:10:53", user_id: 1>, {}]
This is #all_answers:
=> {1=>[#<Answer id: 1, content: "It walked", question_id: 1, correct: false, created_at: "2014-05-07 17:10:14", updated_at: "2014-05-07 17:10:14">, #<Answer id: 2, content: "It was thrown", question_id: 1, correct: true, created_at: "2014-05-07 17:10:14", updated_at: "2014-05-07 17:10:14">, #<Answer id: 3, content: "It got run over and pushed", question_id: 1, correct: false, created_at: "2014-05-07 17:10:14", updated_at: "2014-05-07 17:10:14">], 2=>[#<Answer id: 4, content: "False", question_id: 2, correct: true, created_at: "2014-05-13 16:10:53", updated_at: "2014-05-13 16:10:53">, #<Answer id: 5, content: "True", question_id: 2, correct: false, created_at: "2014-05-13 16:10:53", updated_at: "2014-05-13 16:10:53">]}
This is #test_questions:
=> #<ActiveRecord::Associations::CollectionProxy [#<Question id: 1, content: "How did the chicken cross the road?", question_type: "MC", category: "ip_voice", product_id: 8, active: true, created_at: "2014-05-07 17:10:14", updated_at: "2014-05-07 17:10:14", user_id: 1>, #<Question id: 2, content: "Is this working?", question_type: "TF", category: "ip_voice", product_id: 6, active: true, created_at: "2014-05-13 16:10:53", updated_at: "2014-05-13 16:10:53", user_id: 1>]>
I am new to many Rails/Ruby methods.
I think this is the code you need:
#pdf = []
#test = Test.find(params[:id])
#test_questions = #test.questions
answers = Answer.find(:all)
#all_answers = answers.group_by(&:question_id)
#test_questions.each do |q|
#pdf << q
#pdf += #all_answers[q.id]
end
This should create something like:
=> [#<Question id: 1, content: "How did the chicken cross the road?", question_type: "MC", category: "ip_voice", product_id: 8, active: true, created_at: "2014-05-07 17:10:14", updated_at: "2014-05-07 17:10:14", user_id: 1>, #<Answer id: 1, content: "It walked", question_id: 1, correct: false, created_at: "2014-05-07 17:10:14", updated_at: "2014-05-07 17:10:14">, #<Answer id: 2, content: "It was thrown", question_id: 1, correct: true, created_at: "2014-05-07 17:10:14", updated_at: "2014-05-07 17:10:14">, #<Answer id: 3, content: "It got run over and pushed", question_id: 1, correct: false, created_at: "2014-05-07 17:10:14", updated_at: "2014-05-07 17:10:14">,
#<Question id: 2, content: "Is this working?", question_type: "TF", category: "ip_voice", product_id: 6, active: true, created_at: "2014-05-13 16:10:53", updated_at: "2014-05-13 16:10:53", user_id: 1>, #<Answer id: 4, content: "False", question_id: 2, correct: true, created_at: "2014-05-13 16:10:53", updated_at: "2014-05-13 16:10:53">, #<Answer id: 5, content: "True", question_id: 2, correct: false, created_at: "2014-05-13 16:10:53", updated_at: "2014-05-13 16:10:53">]
What you probably want to do is to have something like this:
class Test < ActiveRecord::Base
has_many :questions
has_many :answers, :through => :questions
end
class Question < ActiveRecord::Base
belongs_to :test
has_many :answers
end
class Answer < ActiveRecord::Base
belongs_to :question
end
And then do:
test = Test.find(params[:id]).joins(:questions, :answers)
This will fetch questions and answers in one query and you can do things like:
test.questions.first.answers
or
test.answers
and for the pdf:
test.questions.each do |q|
pdf = test.questions.collect do |q|
[q, q.answers]
end
how to select data from database based created_at today in rails?
example :
[#<Event id: 1, customer_id: 1, therapist_id: 1, location_id: 1, service_id: 3, walkin: true, cancel: false, cancel_reason: nil, room_id: 5, starts_at: "2014-04-03 21:31:13", stops_at: nil, created_at: "2014-04-14 10:13:52", updated_at: "2014-04-14 10:13:52">, #<Event id: 2, customer_id: 2, therapist_id: 2, location_id: 2, service_id: 2, walkin: false, cancel: false, cancel_reason: nil, room_id: 1, starts_at: "2014-04-05 21:31:13", stops_at: nil, created_at: "2014-04-14 10:13:52", updated_at: "2014-04-14 10:13:52">, #<Event id: 3, customer_id: 1, therapist_id: 2, location_id: 1, service_id: 1, walkin: false, cancel: false, cancel_reason: nil, room_id: 5, starts_at: "2014-04-07 21:31:13", stops_at: nil, created_at: "2014-04-14 10:13:52", updated_at: "2014-04-14 10:13:52">, #<Event id: 4, customer_id: 2, therapist_id: 2, location_id: 2, service_id: 2, walkin: false, cancel: false, cancel_reason: nil, room_id: 1, starts_at: "2014-04-09 21:31:13", stops_at: nil, created_at: "2014-04-14 10:13:52", updated_at: "2014-04-14 10:13:52">, #<Event id: 5, customer_id: 14, therapist_id: 2, location_id: 2, service_id: 1, walkin: true, cancel: false, cancel_reason: "", room_id: 8, starts_at: "2014-04-15 06:47:00", stops_at: "2014-04-15 07:47:00", created_at: "2014-04-15 06:47:14", updated_at: "2014-04-15 06:47:14">]
and when i collect data based created_at today i get result :
<Event id: 5, customer_id: 14, therapist_id: 2, location_id: 2, service_id: 1, walkin: true, cancel: false, cancel_reason: "", room_id: 8, starts_at: "2014-04-15 06:47:00", stops_at: "2014-04-15 07:47:00", created_at: "2014-04-15 06:47:14", updated_at: "2014-04-15 06:47:14">
how to collect all data where data created_at just today in rails?
thanks before
Please try this:
Event.where("DATE(created_at) = DATE(?)", Time.now)
Please have a try with this code.
Event.where("created_at >= ? and created_at <= ?", Time.now.beginning_of_day, Time.now.end_of_day)
To fetch today's events, it will return only today's events
Event.where("created_at = ?", Date.today)
Here's what I have tried in my console
2.0.0p247 :008 > Article.where("created_at < ?", Date.today)
Article Load (0.5ms) SELECT `articles`.* FROM `articles` WHERE (created_at < '2014-04-15')
=> #<ActiveRecord::Relation [#<Article id: 2, title: "Villa Kerylos: A Greek Dream.. A Modern Villa", description: "An inside look at one of the Mediterranean's most i...", url: "http://frenchantiques.blogspot.com/2009/05/villa-ke...", is_open_in_new_window: true, created_at: "2013-12-26 07:03:17", updated_at: "2013-12-26 10:28:36">, #<Article id: 4, title: "Kenzo Auctions Personal Art Collection", description: "Kenzo Auctions Personal Art Collection", url: "http://frenchantiques.blogspot.com/2009/06/kenzo-au...", is_open_in_new_window: false, created_at: "2013-12-26 09:57:21", updated_at: "2013-12-26 09:57:21">]>
Event.where("created_at > ?" Time.now.to_date.to_time) should work, because you want todays entries. Also, a good Idea, is those of the last 24 hours, which should be Event.where("created_at > ?-60*60*24 and created_at < ?" Time.now)
Event.where('created_at >= ?', Date.today)
Maybe you can parse the created_at to the same short format and compare, but this should be enough.
I want to remove elements from an Active Record collection, for this I'm trying to use delete_if. Below is my collection:
categories = Category.all
groups = Group.all
result = []
groups.each do |g|
result.push({ :name => g[:name], :amount => g[amount_column], :drilldown => [] })
categories.where( { :group_id => g.id } ).each do |c, index|
result.last[:drilldown].push({ :name => c[:name], :amount => c[amount_column], :drilldown => nil })
end
# lastly, remove these categories from this collection (not working)
categories.delete_if {|c| c.group_id == g.id }
# tried this too - categories.select! { |c| c.group_id != g.id }
end
abort(categories.size.inspect)
..I want to do something with the categories of each group, then remove them form the array. After the loop block I'll want to be left with the categories which do not belong to a group - that is why I delete those of each group there. Here is the data for groups and categories when they are first fetched (sorry it's a lot but just to note that some category.group_id and group.id match:
#categories
#<ActiveRecord::Associations::CollectionProxy [#<Category id: 13, name: "Internet", user_id: 1, created_at: "2014-03-09 13:15:19", updated_at: "2014-03-15 05:13:47", amount: #<BigDecimal:7f0c283806e0,'0.0',9(18)>, group_id: nil, amount_in: #<BigDecimal:7f0c28380578,'0.0',9(18)>, amount_out: #<BigDecimal:7f0c283804b0,'0.0',9(18)>>, #<Category id: 15, name: "Electricity", user_id: 1, created_at: "2014-03-09 13:15:39", updated_at: "2014-03-15 05:14:03", amount: #<BigDecimal:7f0c2838f5a0,'0.0',9(18)>, group_id: nil, amount_in: #<BigDecimal:7f0c2838f460,'0.0',9(18)>, amount_out: #<BigDecimal:7f0c2838f2f8,'0.0',9(18)>>, #<Category id: 6, name: "Phone", user_id: 1, created_at: "2014-02-18 10:07:47", updated_at: "2014-03-15 05:16:21", amount: #<BigDecimal:7f0c2838e470,'0.0',9(18)>, group_id: nil, amount_in: #<BigDecimal:7f0c2838e308,'0.0',9(18)>, amount_out: #<BigDecimal:7f0c2838e240,'0.0',9(18)>>, #<Category id: 9, name: "Trains", user_id: 1, created_at: "2014-02-22 03:08:08", updated_at: "2014-03-15 05:16:21", amount: #<BigDecimal:7f0c2838d340,'-0.5E3',9(18)>, group_id: nil, amount_in: #<BigDecimal:7f0c2838d138,'0.0',9(18)>, amount_out: #<BigDecimal:7f0c2838cf08,'-0.5E3',9(18)>>, #<Category id: 5, name: "Resaurants", user_id: 1, created_at: "2014-02-17 12:12:44", updated_at: "2014-03-15 05:16:21", amount: #<BigDecimal:7f0c2839be18,'-0.235E3',9(18)>, group_id: 16, amount_in: #<BigDecimal:7f0c2839bc38,'0.0',9(18)>, amount_out: #<BigDecimal:7f0c2839baa8,'-0.235E3',9(18)>>, #<Category id: 14, name: "Gas", user_id: 1, created_at: "2014-03-09 13:15:27", updated_at: "2014-03-15 05:16:21", amount: #<BigDecimal:7f0c2839a680,'0.0',9(18)>, group_id: 16, amount_in: #<BigDecimal:7f0c2839a3d8,'0.0',9(18)>, amount_out: #<BigDecimal:7f0c2839a1d0,'0.0',9(18)>>, #<Category id: 3, name: "Snowboarding", user_id: 1, created_at: "2014-02-11 09:43:52", updated_at: "2014-03-15 05:16:21", amount: #<BigDecimal:7f0c28398d30,'-0.1111E4',9(18)>, group_id: 16, amount_in: #<BigDecimal:7f0c28398b28,'0.0',9(18)>, amount_out: #<BigDecimal:7f0c28398a38,'-0.1111E4',9(18)>>]>
# groups
#<ActiveRecord::Associations::CollectionProxy [#<Group id: 16, name: "Testing", user_id: 1, amount: #<BigDecimal:31c0ce8,'-0.1346E4',9(18)>, created_at: "2014-03-09 13:48:50", updated_at: "2014-03-15 05:35:57", amount_in: #<BigDecimal:31d3118,'0.0',9(18)>, amount_out: #<BigDecimal:26b9728,'-0.1346E4',9(18)>>, #<Group id: 17, name: "test", user_id: 1, amount: #<BigDecimal:31d2a88,'0.0',9(18)>, created_at: "2014-03-15 05:38:36", updated_at: "2014-03-15 05:39:00", amount_in: #<BigDecimal:31d14f8,'0.0',9(18)>, amount_out: #<BigDecimal:2e4e650,'0.0',9(18)>>]>
.. but my delete_if does nothing (abort shows the same size with or without the delete_if). Please note that there are group.id = 16, and category.group_id = 16 so the delete_if should delete those ones - but it doesn't. Is there anything that I'm doing wrong?
Try this ,I think it will help
categories.delete_if {|x| x.group_id==16}
This will update categories in place, selecting all categories with group_id not equal to g.id.
categories.select! { |c| c.group_id != g.id }
I want to print all questions and status fields.
How can I extract the required data in an array ?
This is my array : #category_questions
[#<Question id: 38, user_id: 1, question: "hi", question_status: 1, created_at: "2013-06-04 18:32:28", updated_at: "2013-06-04 18:32:28">, #<Question id: 40, user_id: 1, question: "urll", question_status: 1, created_at: "2013-06-04 18:34:57", updated_at: "2013-06-04 18:34:57">, #<Question id: 41, user_id: 1, question: "urll", question_status: 1, created_at: "2013-06-04 18:35:31", updated_at: "2013-06-04 18:35:31">]
I tried #category_questions[iteration_number][:some field] but it did not work.
To get an array of hashes:
#category_questions.map do |question|
{question: question.question, status: question.question_status}
end
To get an array of arrays:
#category_questions.map {|question| [question.question, question.question_status] }
For a user I have the following as an example:
[#<Permission id: 1, project_id: 3, role_id: 1, user_id: 1>, #<Permission id: 43, project_id: 2, role_id: 1, user_id: 1>, #<Permission id: 44, project_id: 4, role_id: 1, user_id: 1>, #<Permission id: 45, project_id: 5, role_id: 2, user_id: 1>, #<Permission id: 46, project_id: 6, role_id: 3, user_id: 1>, #<Permission id: 47, project_id: 7, role_id: 1, user_id: 1>]
I'm able to do this:
<% if results.permissions.empty? %>
Which tells me if the results.permissions has 1 or more records.
But what I'd like to do is something like this:
<% if results.permissions.where(spaceid = 3).empty? %>
What I'm trying to do is take a project_id variable and filter that with the results.permission object.
Suggestions?
Thanks!
If you are using a :has_many association you should be able to do the following:
results.permissions.find_by_project_id(3)
or if you want to get all the records with that id, you could use:
results.permissions.find_all_by_project_id(3)