I have a strange scenario: I would like to order all posts P by the time at which P's creator and the current user became friends.
The result would be a list of posts with newer friends' posts at the top and older friends' posts at the bottom. We can assume all users are friends of all other users, but each friendship has varying creation times.
I have Post, User, and Friendship models. Posts belong to users and users have many friendships.
class User < ActiveRecord::Base
has_many :friendships
has_many :friends, :through => :friendships
has_many :inverse_friendships, :class_name => "Friendship", :foreign_key => "friend_id"
has_many :inverse_friends, :through => :inverse_friendships, :source => :user
end
class Friendship < ActiveRecord::Base
belongs_to :user
belongs_to :friend, :class_name => "User"
end
class Post < ActiveRecord::Base
belongs_to :user
end
What's the best way to do this? Thanks!
You can order on the associated table by doing a nested join, like so:
@posts = Post.joins(:user => :friendships).order("friendships.friended_at")
Turn Sean Hill's answer into a scope with:
class Post < ActiveRecord::Base
belongs_to :user
scope :ordered, -> {
joins(:user => :friendships).order("friendships.friended_at")
}
end
Just an addendum to this, as a thank you, Sean Hill's answer also works, slightly modified, to sort results using has_many through relationships with fields_for in Rails 4.
So if Messages belong_to both Conversations and Users and you first want a list of Conversations on the User page—perhaps before updating or modifying some message attribute—but sorted by an attribute on Conversations (e.g. "title"), not Messages, you can go from User through Messages to Conversations and Conversation attributes.
In the view:
<% fields_for :messages, @user.messages.joins(:conversation).order("title ASC") do %>
or in the User.rb model:
has_many :messages, -> {joins(:conversation).order("title ASC")}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With