2

我正在创建一个应用程序,在创建和更新文章时需要管理员批准。我使用书面记录来完成此操作,将每次更新存储到文章中。

更新文章时,“已发布”字段设置为 false。因为我想显示文章的最新批准/发布版本,我需要一种范围来检查文章的当前版本是否被批准,如果不是,它会搜索以前的版本,直到找到批准/发布的一个。

def self.published(query={})
  where(query).map do |article|
    article.published? ? article : article.last_published_version
  end.compact! || []
end

def published?()
  published
end

def last_published_version()
  return self if published?
  published_versions = versions.select{ |version| version.reify.try(:published?) } 
  published_versions.present? ? published_versions.last.reify : nil
end

现在,由于我在map这里使用,我的查询返回一个数组而不是 ActiveRecord 关系。我想在已发表的文章上链接其他查询,所以这是一个问题。

例如,我想做: Article.published.where(...).order_by(...)

有什么想法可以做到这一点吗?

4

2 回答 2

1

我建议将两者直接关联joins起来,以便您可以针对版本控制表添加搜索词。我还将使用自定义版本类(不是您不能使用默认版本表执行此操作)并设置您将定期访问(或需要访问以进行搜索)的元数据,因为版本是序列化的,通过他们meta选项。这样可能会更快,搜索/访问数据会更方便。

于 2013-02-10T03:13:21.320 回答
0

如果将 a 添加has_many :versions, as: :item, class_name: 'PaperTrail::Version'到模型中,则可以使用include(:versions). 但是,这不会急切查询所有 PaperTrail 查询,例如version_at因为该查询包含 created_at 范围。除了使用该version_at方法之外,您可以做的事情类似于Foo.includes(:versions).first.versions.find { |f| f.created_at > date }. 这是 PaperTrail 的问题here中建议的。

我想要include(:versions)多个Foo,我在查询 Foo 后对版本进行了单独的查询

    foo_versions = PaperTrail::Version.where(
      item_type: 'Publication',
      item_id: foos.map(&:id),
    ).where("created_at >= ?", date).order(:created_at)

然后我建立了一个查找索引

    foo_index = foo_versions.each_with_object({}) do |foo, mapping|
      mapping[foo.item_id] ||= foo
    end

这使我可以省略 n+1 查询情况。

于 2020-07-30T00:49:46.003 回答