Sort an array object containing activerecord query results using sort method in reverse order (DESC) - ruby-on-rails

I have an array object #questions which is a collection of two Active record query results based on two conditions. #questions have a set of questions along with their attributes. I want to sort it in descending order only by using sort method based on one of its attribute created_at.
Please help to get that work :)-

I got it.
There is a ruby way of doing it on array object #questions.
#questions = #questions.sort { |value1, value2| value2.created_at <=> value1.created_at }
The above just works fine for me.

try this one
#questions = Question.order("created_at desc")

Related

How can i convert an array to an rails ActiveRecord::Relation without changing array order?

I have number of restaurants. On the fly i sorted out restaurants and stored to an array. Later I converted this array to rails object. When I did this array sorted order gone. How can I keep array order while converting to an rails object?
Edit:-
#restaurants = [res1,res2,res3,res4,res5]
sorted_array = [res1,res5,res2,res4,res3]
#places =Restaurant.where(:id=> sorted_array.map(:&id))
then i got below order of rails objects
#places = [res1,res2,res3,res4,res5]
I want to order like below when I convert an array to a rails object.
How can I get same order as an array ?
#places = [res1,res5,res2,res4,res3]
This seems to do what you want (res1 ... res5 should be Restaurant objects)
ids = [res1,res5,res2,res4,res3].map(&:id)
#places = Restaurant.where(id: ids).order("FIELD(id, #{ids.join(',')})").all
More info, Maintaining order in MySQL "IN" query
Is that sorted array an array of Restaurant records? Curious because you're
trying to call #id on the map block. Where are res1-res5 defined?
Another thing to note is your & syntax looks off, I think you need to say sorted_array.map(&:id), otherwise it's trying to call #&id on each restaurant record.
If it's a small array length like 5, in this case, you could map from the sorted array:
#places = sorted_array.map { |restaurant| Restaurant.find(restaurant.id) }

RoR: How to sort an array with the help of scopes

I have an array #products. Each element of the array is a hash, containing a few fields (but not all) from Product table and the corresponding values.
I have a scope descend_by_popularity in Product which allows me to sort the products based on popularity field. I'd like to sort the array #products using this scope.
What I tried:
#product_group = Array.new
#products.each do |product|
#product_group.push(Product.find(product['id']))
end
#product_group1 = #product_group.descend_by_popularity
But this gives me error:
undefined method `descend_by_popularity' for #<Array:0xb2497200>
I also want to change the sorted Product list back to the format of #products array.
Thanks
Scopes only make sense within the ActiveRecord context for requests to the database (since it is used to change the SQL query). What you did is throwing a lot of products into an array. This array then knows nothing about the scope anymore. You would have to use the scope when you create the #products object. (and it does not seem to make a lot of sense to move the result of a query into an array)
So something like
#products = Product.descend_by_popularity.where(some more stuff)
should work for you. After that you should have the records in the order defined by the scope and can then either use them directly or still push them into an array if that's what you want to do.
With the updated info from the comments it looks like maybe the best way to go would be to first collect only the Product ids from the solr response into an array and then run that as search together with your scope:
#product_group = #products.map{|product| product.id}
#result = Product.where(id: #product_group).descend_by_popularity
this should technically work, peformance is a different question. I would consider aggregating this data into the Solr document, if it doesn't change too often.
Now assuming you are only interested in the order of products as such, you could do something like this to get #products into this order:
#result.map{|r| #products.find{|p| p[:id] == r.id}
though this may slow down things a bit.
Try this: find_by_id as params
#product_group = Array.new
#products.each do |product|
#product_group.push(Product.find(params['id']))
end
and return the array of #product_group
#product_group1 = #product_group.descend_by_popularity

Ruby on Rails: where returning nil

In my app I'm obtaining a certain category, and I'm filtering the associated items based on their name.
The following code should be pretty clear:
categories = Category.where(:id => params[:category_id]).includes(:items).where("lower(items.name) like ?", "%#{params[:keywords].downcase}%")
However, if the name filter excludes all the items, the categories object returned by where is nil. Is this the expected behaviour? How can I get the category even either items exist or not?
The easiest way might be to just split the query:
#category = Category.find(params[:category_id])
#items = #category.items.where("lower(items.name) like ?", "%#{params[:keywords].downcase}%")
Based on your code it seems like category_id references only 1 category so I've changed it to singular.
You should look into doing an OUTER JOIN against the items table which will give you categories regardless of whether or not their items meet the name filter.

ActiveRecord not showing right records

In Rails 3, when I write:
#users = User.limit(10).sort_by(&:name)
it is giving me 10 users in name order, but not the first 10 alphabetically like I want. What am I doing wrong?
Thanks!
Try:
#users = User.limit(10).order('name ASC')
The sort_by method is from Enumerable. So, in order to call sort_by, ActiveRecord has to retrieve the records from the database; ActiveRecord will first do this:
User.limit(10)
to get ten records from the database and then those records will be sorted (in Ruby) using their names. The end result is that the records will have been extracted from the database before they're sorted.
The solution is to listen to Alex Peattie and use the order method.

rails where() sql query on array

I'll explain this as best as possible. I have a query on user posts:
#selected_posts = Posts.where(:category => "Baseball")
I would like to write the following statement. Here it is in pseudo terms:
User.where(user has a post in #selected_posts)
Keep in mind that I have a many to many relationship setup so post.user is usable.
Any ideas?
/EDIT
#posts_matches = User.includes(#selected_posts).map{ |user|
[user.company_name, user.posts.count, user.username]
}.sort
Basically, I need the above to work so that it uses the users that HAVE posts in selected_posts and not EVERY user we have in our database.
Try this:
user.posts.where("posts.category = ?", "Baseball")
Edit 1:
user.posts.where("posts.id IN (?)", #selected_posts)
Edit 2:
User.select("users.company_name, count(posts.id) userpost_count, user.username").
joins(:posts).
where("posts.id IN (?)", #selected_posts).
order("users.company_name, userpost_count, user.username")
Just use the following:
User.find(#selected_posts.map(&:user_id).uniq)
This takes the user ids from all the selected posts, turns them into an array, and removes any duplicates. Passing an array to user will just find all the users with matching ids. Problem solved.
To combine this with what you showed in your question, you could write:
#posts_matches = User.find(#selected_posts.map(&:user_id).uniq).map{ |user|
[user.company_name, user.posts.size, user.username]
}
Use size to count a relation instead of count because Rails caches the size method and automatically won't look it up more than once. This is better for performance.
Not sure what you were trying to accomplish with Array#sort at the end of your query, but you could always do something like:
#users_with_posts_in_selected = User.find(#selected_posts.map(&:user_id).uniq).order('username DESC')
I don't understand your question but you can pass an array to the where method like this:
where(:id => #selected_posts.map(&:id))
and it will create a SQL query like WHERE id IN (1,2,3,4)
By virtue of your associations your selected posts already have the users:
#selected_posts = Posts.where("posts.category =?", "Baseball")
#users = #selected_posts.collect(&:user);
You'll probably want to remove duplicate users from #users.

Resources