【问题标题】:Combining two ActiveRecord queries with pagination将两个 ActiveRecord 查询与分页相结合
【发布时间】:2015-11-07 23:59:20
【问题描述】:

我有两个活动记录查询:

feedbacks = Activity.where(subject_type: Feedback.name).select{ |f| f.subject.application == @application }
activities = Activity.where(subject: @application)
                    .order(created_at: :desc).page(params[:page])
                    .per(10) + feedbacks

我觉得必须有更好的方法来组合这两个查询的结果。此外,由于feedbacks 可能返回n 记录,因此分页无法正常工作。

如果我在两个查询中都添加了分页,那么我可以得到比我实际想要显示的双倍的项目。

编辑:这是一个似乎有效的尝试,虽然 - 不漂亮:

activities = Activity.where('subject_id = ? OR subject_type = ?', @application.id, Feedback.name)
  .order(created_at: :desc)
  .page(params[:page])
  .per(20).select { |record|
    if record.subject_type == Feedback.name
      record.subject.application == @application
    else
      true
    end
  }

【问题讨论】:

  • 主题是多态关联吗?
  • @NicolasMaloeuvre 是的,是的
  • 您的分页是由 Kaminari 处理的吗?在 Kaminari 中,您可以在配置文件中设置默认分页(请参阅他们的文档;您需要安装单独的配置文件)。我不确定这是否能解决您的所有问题,但它应该处理每页的总数。
  • 你的最后一个例子和你的第一个不一样,它没有检查(subject_id == @application.id AND subject_type == @application.type) || subject_type == "Feedback"

标签: ruby-on-rails activerecord pagination


【解决方案1】:

将此添加到您的活动模型中:

belongs_to :feedback, -> { where(activities: {subject_type: 'Feedback'}) }, foreign_key: 'subject_id'

然后在你的控制器中:

feedbacks = Activity.includes(:feedback).where(feedbacks:{application:@application})
other_activities = Activity.where(subject: @application)
matching_ids = (feedbacks.map(&:id)+other_activities.map(&:id))
activities = Activity.where(id:matching_ids).order(created_at: :desc).page(params[:page])

此解决方案不是真正可扩展的,由于基于多态关联的两个条件,您应该进行相当复杂的查询

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-02-28
    • 2011-04-05
    • 1970-01-01
    • 1970-01-01
    • 2020-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多