Get posts from different users - ruby-on-rails

So, i have 100 posts from 10 users, and i want to get a collection of 5 posts, but always from different user.
So Post.where(active: true).order(:created_at).limit(5)... works.
Any help?

You can select distinct User IDs:
Post.select("DISTINCT(user_id)").where(active: true).limit(5)

Related

Sort Users by Number of Followers

I'm using a simple follower system in my application and I can get the number of any user's followers by running User.followers.count. However, when I try to sort all users by the number of followers they each have with #orderedUsers = User.all.order("followers.count DESC") it returns the error "ActiveRecord::StatementInvalid: SQLite3::SQLException: no such column: followers.count". Obviously, this is because there is no such column. Is there a way to work around this to do what I wish to achieve?
Thanks.
This code should work (assuming the DB table names are users and followers):
User.joins(:followers).order("count(followers.user_id) desc")
How about something like:
#ordered_users = User.all.sort{|a,b| a.followers.count <=> b.followers.count}
For the reverse order, you can do:
#ordered_users = User.all.sort{|a,b| b.followers.count <=> a.followers.count}
Or, .reverse, as you say in the comments.
EDIT: #Alex Quach left a good alternative in a different post. I've modified it for where it will not include the current user in the list, which may be helpful:
User.all.where('id != ?', current_user.id).sort_by { |u| -u.followers.count }
I would strongly consider using a counter cache on the User model, to hold the count of followers.
This would give a very small performance impact on adding or removing followers, and greatly increase performance when performing sorts:
User.order(followers_count: :desc)
This would be particularly noticeable if you wanted the top-n users by follower count, or finding users with no followers.

get popular records by id in rails

I have a table in my db that records the amount of times the page has been viewed by id.
The table records the event id and what im ideally wanting to do is count how many times the event id shows.
That way i can put the popular events on my homepage
Basically it looks like this
MY table:
ID
1
1
1
2
2
3
3
3
3
This way the returning result would be something like this:
3 would be first, 1 would be second and 2 would be third.
Then what i can do is each result would populate an each in the show on the view.
Any ideas how to do this?
Thanks!
In my memory I think
Model.group(:event_id).order(":count_event_id DESC").count(:event_id)
would work when I tried.

Search and group products by shops REDIS

I found this question about Group By in redis but actually does not solve my issue. I have a complex search of products, once I got the ones I am looking for I want to group them by their shops, because they must be showed in a map.
My actual implementation is as follow:
-A function which search products by a pattern, it return products ids as "product:id"
product_ids = search_products_by_indexing(pattern)
-A hash with name "selling" which contains product:id/shop:id as key/value.
shops = $redis.hmget("selling", *product_ids)
# this returns list of shops as "shop:id" which sell the given prodcuts
-Then I do an intersection of shops with another list to get only shops located in a given city.
result_shops = shops & $redis.smembers("shops:city_name")
# OR by redis
$zinterstore(tem_id, shops, $redis.smembers("shops:city_name"))
result_shops = $redis.zrange(temp_id, 0, -1)
-The only thing I still need is to get the searched products grouped by result_shops. or for example this could be a hash as shop:id/[product:id] as key/value (this is the final result, shop must be in the city and product match the pattern)
Is my solution suitable to this problem or maybe there is a better implementation to solve it? any suggestion will be very appreciated!!
UPDATE: One product belongs to only one shop and one shop can have many products.
-A hash with name "selling" which contains product:id/shop:id as key/value.
This usage of a Hash will only allow you to one shop:id per product:id, meaning only one shop can sell a given product... perhaps the value should be a concatenated list of shop:ids or even better - use a Set selling:product:id and store all your relevant shop:ids in it.
-Then I do an intersection of shops with another list to get only shops located in a given city.
IMO this is redundant as the intersect's results is always shops:city_name
-The only thing I still need is to get the searched products grouped by result_shops.
If you've taken my Set instead of a Hash suggestion, this can be done with:
ZINTERSTORE tem_id 2 shops:city_name selling:product:id
ZRANGE tem_id 0 -1

Return all users given user chats with and the latest message in conversation

my relationships look like this
A-[:CHATS_WITH]->B - denotes that the user have sent at least 1 mesg to the other user
then messages
A-[:FROM]->message-[:SENT_TO]->B
and vice versa
B-[:FROM]->message-[:SENT_TO]->A
and so on
now i would like to select all users a given user chats with together with the latest message between the two.
for now i have managed to get all messages between two users with this query
MATCH (me:user)-[:CHATS_WITH]->(other:user) WHERE me.nick = 'bazo'
WITH me, other
MATCH me-[:FROM|:SENT_TO]-(m:message)-[:FROM|:SENT_TO]-other
RETURN other,m ORDER BY m.timestamp DESC
how can I return just the latest message for each conversation?
Taking what you already have do you just want to tag LIMIT 1 to the end of the query?
The preferential way in a graph store is to manually manage a linked list to model the interaction stream in which case you'd just select the head or tail of the list. This is because you are playing to the graphs strengths (traversal) rather than reading data out of every Message node.
EDIT - Last message to each distinct contact.
I think you'll have to collect all the messages into an ordered collection and then return the head, but this sounds like it get get very slow if you have many friends/messages.
MATCH (me:user)-[:CHATS_WITH]->(other:user) WHERE me.nick = 'bazo'
WITH me, other
MATCH me-[:FROM|:SENT_TO]-(m:message)-[:FROM|:SENT_TO]-other
WITH other, m
ORDER BY m.timestamp DESC
RETURN other, HEAD(COLLECT(m))
See: Neo Linked Lists and Neo Modelling a Newsfeed.

Count returns the count of all joined data instead of the main object

I'm trying to count users who have dogs.
User.joins(:pets).where("pets.type = ?", :dog).count
This returns the count of the users + their dogs combined, instead i just want the count of actual users.
What am i doing wrong?
Update
I've also tried to just fetch the users using the above query and it returns an array of the same users repeated multiple times depending on how many dogs they have.
Try this:
User.joins(:pets).where("pets.type = ?", :dog).count(distinct: true)
See api doc.
The joins would return all the duplicate rows for which the user has multiple associations...
For example if a user, U1 has one dog and user, U2 has two dogs then total three rows would be returned by the joins....so instead of using joins, try to use the includes option...
refer to this Railscast, http://railscasts.com/episodes/181-include-vs-joins for more...

Resources