【问题标题】:Union between two ActiveRecord::Relations两个 ActiveRecord::Relations 之间的联合
【发布时间】:2012-08-25 16:17:37
【问题描述】:

我需要在我发送的消息和我从某人那里收到的消息之间进行联合。

这是我在控制器中尝试做的第一件事,但消息没有排序。我想我需要做一个真正的工会?

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

这是我的用户模型:

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

【问题讨论】:

    标签: ruby-on-rails activerecord ruby-on-rails-3.2


    【解决方案1】:

    当您对结果使用+ 时,您的消息首先加载到内存中的数组中,然后将这些数组连接起来。因此,为了保存排序,您应该再次对其进行排序。丑陋...而且当历史变大时非常缓慢。

    您可以使用真正的 UNION,但它需要大量原始 sql(通过Message.find_by_sql("your union query")),这非常丑陋且难以维护。

    在您的情况下,使用 OR 代替 UNION 可能会更好:

    @messages = Message.where('(sender_id = ? AND recipient_id = ?) OR (recipient_id = ? AND sender_id = ?)', current_user.id, params[:sender_id], current_user.id, params[:sender_id])
    

    还有另一种(在我看来,稍微优雅一点)使用 IN 操作的解决方案(仅当您的用户无法向自己发送消息时才有效):

    @messages = Message.where(:sender_id => [current_user.id, params[:sender_id]], :recipient_id => [current_user.id, params[:sender_id])
    

    在这两种解决方案中,您都可以像往常一样使用排序或分页。

    【讨论】:

      【解决方案2】:

      如果您不必用作活动记录,您可以这样做。
      这意味着,您不需要额外的 where 条件。

      @message = @message1.to_set + @message2.to_set
      

      @message = @message1.to_a + @message2.to_a
      

      但如果您确实需要将结果用作活动记录,则可能会像这样影响性能。

      messages_set = @message1.map { |m| m.id }.to_set + @message2.map { |m| m.id }.to_set
      @message = Message.where(:id => messages_set.to_a)
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-04-27
        • 2015-08-22
        • 1970-01-01
        • 1970-01-01
        • 2015-02-05
        相关资源
        最近更新 更多