Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
张重言
rails
提交
b6799161
R
rails
项目概览
张重言
/
rails
通知
1
Star
0
Fork
0
代码
文件
提交
分支
Tags
贡献者
分支图
Diff
Issue
0
列表
看板
标记
里程碑
合并请求
0
Wiki
0
Wiki
分析
仓库
DevOps
项目成员
Pages
R
rails
项目概览
项目概览
详情
发布
仓库
仓库
文件
提交
分支
标签
贡献者
分支图
比较
Issue
0
Issue
0
列表
看板
标记
里程碑
合并请求
0
合并请求
0
Pages
分析
分析
仓库分析
DevOps
Wiki
0
Wiki
成员
成员
收起侧边栏
关闭侧边栏
动态
分支图
创建新Issue
提交
Issue看板
前往新版Gitcode,体验更适合开发者的 AI 搜索 >>
提交
b6799161
编写于
2月 13, 2016
作者:
B
Bogdan Gusiev
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Make ActiveRecord::Relation#last to reverse SQL order
instead of loading the relation into memory
上级
a88c5ff9
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
78 addition
and
17 deletion
+78
-17
activerecord/CHANGELOG.md
activerecord/CHANGELOG.md
+21
-0
activerecord/lib/active_record/relation/finder_methods.rb
activerecord/lib/active_record/relation/finder_methods.rb
+19
-9
activerecord/lib/active_record/relation/query_methods.rb
activerecord/lib/active_record/relation/query_methods.rb
+2
-0
activerecord/test/cases/finder_test.rb
activerecord/test/cases/finder_test.rb
+36
-8
未找到文件。
activerecord/CHANGELOG.md
浏览文件 @
b6799161
*
Rework
`ActiveRecord::Relation#last`
1.
Never perform additional SQL on loaded relation
2.
Use SQL reverse order instead of loading relation if relation doesn't have limit
3.
Deprecated relation loading when SQL order can not be automatically reversed
Topic.order("title").load.last(3)
# before: SELECT ...
# after: No SQL
Topic.order("title").last
# before: SELECT * FROM `topics`
# after: SELECT * FROM `topics` ORDER BY `topics`.`title` DESC LIMIT 1
Topic.order("coalesce(author, title)").last
# before: SELECT * FROM `topics`
# after: Deprecation Warning for irreversible order
*Bogdan Gusiev*
*
Allow
`joins`
to be unscoped.
Closes #13775.
...
...
activerecord/lib/active_record/relation/finder_methods.rb
浏览文件 @
b6799161
...
...
@@ -145,15 +145,21 @@ def first!
#
# [#<Person id:4>, #<Person id:3>, #<Person id:2>]
def
last
(
limit
=
nil
)
if
limit
if
order_values
.
empty?
&&
primary_key
order
(
arel_attribute
(
primary_key
).
desc
).
limit
(
limit
).
reverse
else
to_a
.
last
(
limit
)
end
else
find_last
end
return
find_last
(
limit
)
if
loaded?
||
limit_value
result
=
limit
(
limit
||
1
)
result
.
order!
(
arel_attribute
(
primary_key
))
if
order_values
.
empty?
&&
primary_key
result
=
result
.
reverse_order!
limit
?
result
.
reverse
:
result
.
first
rescue
ActiveRecord
::
IrreversibleOrderError
ActiveSupport
::
Deprecation
.
warn
(
<<-
WARNING
.
squish
)
Finding a last element by loading the relation when SQL ORDER
can not be reversed is deprecated.
Rails 5.1 will raise ActiveRecord::IrreversibleOrderError in this case.
Please call `to_a.last` if you still want to load the relation.
WARNING
find_last
(
limit
)
end
# Same as #last but raises ActiveRecord::RecordNotFound if no record
...
...
@@ -578,5 +584,9 @@ def find_nth_with_limit_and_offset(index, limit, offset:) # :nodoc:
find_nth_with_limit
(
index
,
limit
)
end
end
def
find_last
(
limit
)
limit
?
to_a
.
last
(
limit
)
:
to_a
.
last
end
end
end
activerecord/lib/active_record/relation/query_methods.rb
浏览文件 @
b6799161
...
...
@@ -1112,6 +1112,8 @@ def reverse_sql_order(order_query)
order_query
.
flat_map
do
|
o
|
case
o
when
Arel
::
Attribute
o
.
desc
when
Arel
::
Nodes
::
Ordering
o
.
reverse
when
String
...
...
activerecord/test/cases/finder_test.rb
浏览文件 @
b6799161
...
...
@@ -516,16 +516,44 @@ def test_last_with_integer_and_order_should_keep_the_order
assert_equal
Topic
.
order
(
"title"
).
to_a
.
last
(
2
),
Topic
.
order
(
"title"
).
last
(
2
)
end
def
test_last_with_integer_and_order_should_
not_
use_sql_limit
query
=
assert_sql
{
Topic
.
order
(
"title"
).
last
(
5
).
entries
}
assert_
equal
1
,
query
.
length
assert
_no_match
(
/LIMIT/
,
query
.
first
)
def
test_last_with_integer_and_order_should_use_sql_limit
relation
=
Topic
.
order
(
"title"
)
assert_
queries
(
1
)
{
relation
.
last
(
5
)
}
assert
!
relation
.
loaded?
end
def
test_last_with_integer_and_reorder_should_not_use_sql_limit
query
=
assert_sql
{
Topic
.
reorder
(
"title"
).
last
(
5
).
entries
}
assert_equal
1
,
query
.
length
assert_no_match
(
/LIMIT/
,
query
.
first
)
def
test_last_with_integer_and_reorder_should_use_sql_limit
relation
=
Topic
.
reorder
(
"title"
)
assert_queries
(
1
)
{
relation
.
last
(
5
)
}
assert
!
relation
.
loaded?
end
def
test_last_on_loaded_relation_should_not_use_sql
relation
=
Topic
.
limit
(
10
).
load
assert_no_queries
do
relation
.
last
relation
.
last
(
2
)
end
end
def
test_last_with_irreversible_order
assert_deprecated
do
Topic
.
order
(
"coalesce(author_name, title)"
).
last
end
end
def
test_last_on_relation_with_limit_and_offset
post
=
posts
(
'sti_comments'
)
comments
=
post
.
comments
.
order
(
id: :asc
)
assert_equal
comments
.
limit
(
2
).
to_a
.
last
,
comments
.
limit
(
2
).
last
assert_equal
comments
.
limit
(
2
).
to_a
.
last
(
2
),
comments
.
limit
(
2
).
last
(
2
)
assert_equal
comments
.
limit
(
2
).
to_a
.
last
(
3
),
comments
.
limit
(
2
).
last
(
3
)
comments
=
comments
.
offset
(
1
)
assert_equal
comments
.
limit
(
2
).
to_a
.
last
,
comments
.
limit
(
2
).
last
assert_equal
comments
.
limit
(
2
).
to_a
.
last
(
2
),
comments
.
limit
(
2
).
last
(
2
)
assert_equal
comments
.
limit
(
2
).
to_a
.
last
(
3
),
comments
.
limit
(
2
).
last
(
3
)
end
def
test_take_and_first_and_last_with_integer_should_return_an_array
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录