Pre*_*her 7 ruby-on-rails ruby-on-rails-3
我需要返回十个记录才能在视图中使用.我有一个高度限制性的查询我想使用,但我想要一个限制较少的查询来填写结果,以防第一个查询没有产生十个结果.
只是玩了几分钟,这就是我想出来的,但它不起作用.我认为它不起作用,因为合并意味着在不同的模型上组合查询,但我可能是错的.
class Article < ActiveRecord::Base
...
def self.listed_articles
Article.published.order('created_at DESC').limit(25).where('listed = ?', true)
end
def self.rescue_articles
Article.published.order('created_at DESC').where('listed != ?', true).limit(10)
end
def self.current
Article.rescue_articles.merge(Article.listed_articles).limit(10)
end
...
end
Run Code Online (Sandbox Code Playgroud)
查看控制台,这会强制查询rescue_articles中查询中的lists_articles限制,显示如下内容:
Article Load (0.2ms) SELECT `articles`.* FROM `articles` WHERE (published = 1) AND (listed = 1) AND (listed != 1) ORDER BY created_at DESC LIMIT 4
Article Load (0.2ms) SELECT `articles`.* FROM `articles` WHERE (published = 1) AND (listed = 1) AND (listed != 1) ORDER BY created_at DESC LIMIT 6 OFFSET 4
Run Code Online (Sandbox Code Playgroud)
我确信文档中缺少一些可笑的简单方法,但我还没有找到它.
编辑:我想做的是返回最近25篇文章中列出的所有文章.如果这不能得到我的十篇文章,我想在最近的文章中添加足够的文章,其中列出的不是真的,以获得我的十篇文章.
编辑#2:换句话说,合并方法似乎将查询串起来进行一次长查询而不是合并结果.我需要两个查询的前十个结果(列出所列文章的优先级),而不是一个长查询.
Yul*_*ule 11
使用您的初始代码:
您可以使用+加入两个数组,然后获得前10个结果:
def self.current
(Article.listed_articles + Article.rescue_articles)[0..9]
end
Run Code Online (Sandbox Code Playgroud)
我想一个非常脏的做法是:
def self.current
oldest_accepted = Article.published.order('created_at DESC').limit(25).last
Artcile.published.where(['created_at > ?', oldest_accepted.created_at]).order('listed DESC').limit(10)
end
Run Code Online (Sandbox Code Playgroud)
如果你想要一个ActiveRecord::Relation
对象而不是数组,你可以使用:
安装 gem:gem install active_record_union
并使用:
def self.current
Article.rescue_articles.union(Article.listed_articles).limit(10)
end
Run Code Online (Sandbox Code Playgroud)创建模块 UnionScope (lib/active_record/union_scope.rb)。
module ActiveRecord::UnionScope
def self.included(base)
base.send :extend, ClassMethods
end
module ClassMethods
def union_scope(*scopes)
id_column = "#{table_name}.id"
if (sub_query = scopes.reject { |sc| sc.count == 0 }.map { |s| "(#{s.select(id_column).to_sql})" }.join(" UNION ")).present?
where "#{id_column} IN (#{sub_query})"
else
none
end
end
end
end
Run Code Online (Sandbox Code Playgroud)
然后在您的 Article 模型中调用它。
class Article < ActiveRecord::Base
include ActiveRecord::UnionScope
...
def self.current
union_scope(Article.rescue_articles, Article.listed_articles).limit(10)
end
...
end
Run Code Online (Sandbox Code Playgroud) 归档时间: |
|
查看次数: |
18834 次 |
最近记录: |