I need to do a union between the messages I sent and the messages I received from someone.
Here is the first thing I tried to do in my controller, but the messages are not ordered. I think I need to do a real union?
def listmessages
@messages1 = current_user.messages.where(:sender_id => params[:sender_id])
@messages2 = current_user.sent_messages.where(:recipient_id => params[:sender_id])
@messages = @messages1 + @messages2
end
Here is my User model:
class User < ActiveRecord::Base
before_create :distribute_points
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable, :confirmable
has_many :sent_messages, foreign_key: "sender_id", class_name:"Message",
order: "created_at DESC"
has_many :messages, foreign_key: "recipient_id", order: "created_at DESC"
end
When you use
+on results, your messages first loaded into arrays in memory and then these arrays are concatenated. So to save ordering you should sort it again. Ugly… And very slow when history becomes big.You may use real UNION but it requires a lot of raw sql (through
Message.find_by_sql("your union query")), which is very ugly and hard to maintain.In your case it may be better to use OR instead UNION:
And there is another (and in my opinion, slightly more ellegant) solution using IN operation (which will work only if your users can’t send messages to themself):
In both solutions you may use ordering or pagination as usually.