Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
张重言
rails
提交
7aabaac0
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 搜索 >>
提交
7aabaac0
编写于
12月 30, 2009
作者:
P
Pratik Naik
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Organize Relation methods into separate modules
上级
97204fc0
变更
5
隐藏空白更改
内联
并排
Showing
5 changed file
with
262 addition
and
241 deletion
+262
-241
activerecord/lib/active_record.rb
activerecord/lib/active_record.rb
+8
-1
activerecord/lib/active_record/relation.rb
activerecord/lib/active_record/relation.rb
+1
-239
activerecord/lib/active_record/relation/calculation_methods.rb
...erecord/lib/active_record/relation/calculation_methods.rb
+1
-1
activerecord/lib/active_record/relation/finder_methods.rb
activerecord/lib/active_record/relation/finder_methods.rb
+120
-0
activerecord/lib/active_record/relation/query_methods.rb
activerecord/lib/active_record/relation/query_methods.rb
+132
-0
未找到文件。
activerecord/lib/active_record.rb
浏览文件 @
7aabaac0
...
...
@@ -47,8 +47,15 @@ module ActiveRecord
autoload
:AttributeMethods
autoload
:Attributes
autoload
:AutosaveAssociation
autoload
:Relation
autoload
:RelationalCalculations
autoload_under
'relation'
do
autoload
:QueryMethods
autoload
:FinderMethods
autoload
:CalculationMethods
end
autoload
:Base
autoload
:Batches
autoload
:Calculations
...
...
activerecord/lib/active_record/relation.rb
浏览文件 @
7aabaac0
module
ActiveRecord
class
Relation
include
RelationalCalculation
s
include
QueryMethods
,
FinderMethods
,
CalculationMethod
s
delegate
:to_sql
,
:to
=>
:relation
delegate
:length
,
:collect
,
:map
,
:each
,
:all?
,
:to
=>
:to_a
...
...
@@ -32,119 +32,6 @@ def merge(r)
alias
:&
:merge
def
preload
(
*
associations
)
spawn
.
tap
{
|
r
|
r
.
preload_associations
+=
Array
.
wrap
(
associations
)
}
end
def
eager_load
(
*
associations
)
spawn
.
tap
{
|
r
|
r
.
eager_load_associations
+=
Array
.
wrap
(
associations
)
}
end
def
readonly
(
status
=
true
)
spawn
.
tap
{
|
r
|
r
.
readonly
=
status
}
end
def
select
(
selects
)
if
selects
.
present?
relation
=
spawn
(
@relation
.
project
(
selects
))
relation
.
readonly
=
@relation
.
joins
(
relation
).
present?
?
false
:
@readonly
relation
else
spawn
end
end
def
from
(
from
)
from
.
present?
?
spawn
(
@relation
.
from
(
from
))
:
spawn
end
def
having
(
*
args
)
return
spawn
if
args
.
blank?
if
[
String
,
Hash
,
Array
].
include?
(
args
.
first
.
class
)
havings
=
@klass
.
send
(
:merge_conditions
,
args
.
size
>
1
?
Array
.
wrap
(
args
)
:
args
.
first
)
else
havings
=
args
.
first
end
spawn
(
@relation
.
having
(
havings
))
end
def
group
(
groups
)
groups
.
present?
?
spawn
(
@relation
.
group
(
groups
))
:
spawn
end
def
order
(
orders
)
orders
.
present?
?
spawn
(
@relation
.
order
(
orders
))
:
spawn
end
def
lock
(
locks
=
true
)
case
locks
when
String
spawn
(
@relation
.
lock
(
locks
))
when
TrueClass
,
NilClass
spawn
(
@relation
.
lock
)
else
spawn
end
end
def
reverse_order
relation
=
spawn
relation
.
instance_variable_set
(
:@orders
,
nil
)
order_clause
=
@relation
.
send
(
:order_clauses
).
join
(
', '
)
if
order_clause
.
present?
relation
.
order
(
reverse_sql_order
(
order_clause
))
else
relation
.
order
(
"
#{
@klass
.
table_name
}
.
#{
@klass
.
primary_key
}
DESC"
)
end
end
def
limit
(
limits
)
limits
.
present?
?
spawn
(
@relation
.
take
(
limits
))
:
spawn
end
def
offset
(
offsets
)
offsets
.
present?
?
spawn
(
@relation
.
skip
(
offsets
))
:
spawn
end
def
on
(
join
)
spawn
(
@relation
.
on
(
join
))
end
def
joins
(
join
,
join_type
=
nil
)
return
spawn
if
join
.
blank?
join_relation
=
case
join
when
String
@relation
.
join
(
join
)
when
Hash
,
Array
,
Symbol
if
@klass
.
send
(
:array_of_strings?
,
join
)
@relation
.
join
(
join
.
join
(
' '
))
else
@relation
.
join
(
@klass
.
send
(
:build_association_joins
,
join
))
end
else
@relation
.
join
(
join
,
join_type
)
end
spawn
(
join_relation
).
tap
{
|
r
|
r
.
readonly
=
true
}
end
def
where
(
*
args
)
return
spawn
if
args
.
blank?
if
[
String
,
Hash
,
Array
].
include?
(
args
.
first
.
class
)
conditions
=
@klass
.
send
(
:merge_conditions
,
args
.
size
>
1
?
Array
.
wrap
(
args
)
:
args
.
first
)
conditions
=
Arel
::
SqlLiteral
.
new
(
conditions
)
if
conditions
else
conditions
=
args
.
first
end
spawn
(
@relation
.
where
(
conditions
))
end
def
respond_to?
(
method
,
include_private
=
false
)
return
true
if
@relation
.
respond_to?
(
method
,
include_private
)
||
Array
.
method_defined?
(
method
)
...
...
@@ -189,47 +76,6 @@ def to_a
alias
all
to_a
def
find
(
*
ids
,
&
block
)
return
to_a
.
find
(
&
block
)
if
block_given?
expects_array
=
ids
.
first
.
kind_of?
(
Array
)
return
ids
.
first
if
expects_array
&&
ids
.
first
.
empty?
ids
=
ids
.
flatten
.
compact
.
uniq
case
ids
.
size
when
0
raise
RecordNotFound
,
"Couldn't find
#{
@klass
.
name
}
without an ID"
when
1
result
=
find_one
(
ids
.
first
)
expects_array
?
[
result
]
:
result
else
find_some
(
ids
)
end
end
def
exists?
(
id
=
nil
)
relation
=
select
(
"
#{
@klass
.
quoted_table_name
}
.
#{
@klass
.
primary_key
}
"
).
limit
(
1
)
relation
=
relation
.
where
(
@klass
.
primary_key
=>
id
)
if
id
relation
.
first
?
true
:
false
end
def
first
if
loaded?
@records
.
first
else
@first
||=
limit
(
1
).
to_a
[
0
]
end
end
def
last
if
loaded?
@records
.
last
else
@last
||=
reverse_order
.
limit
(
1
).
to_a
[
0
]
end
end
def
size
loaded?
?
@records
.
length
:
count
end
...
...
@@ -307,93 +153,9 @@ def method_missing(method, *args, &block)
end
end
def
find_by_attributes
(
match
,
attributes
,
*
args
)
conditions
=
attributes
.
inject
({})
{
|
h
,
a
|
h
[
a
]
=
args
[
attributes
.
index
(
a
)];
h
}
result
=
where
(
conditions
).
send
(
match
.
finder
)
if
match
.
bang?
&&
result
.
blank?
raise
RecordNotFound
,
"Couldn't find
#{
@klass
.
name
}
with
#{
conditions
.
to_a
.
collect
{
|
p
|
p
.
join
(
' = '
)
}
.join(', ')}"
else
result
end
end
def
find_or_instantiator_by_attributes
(
match
,
attributes
,
*
args
)
guard_protected_attributes
=
false
if
args
[
0
].
is_a?
(
Hash
)
guard_protected_attributes
=
true
attributes_for_create
=
args
[
0
].
with_indifferent_access
conditions
=
attributes_for_create
.
slice
(
*
attributes
).
symbolize_keys
else
attributes_for_create
=
conditions
=
attributes
.
inject
({})
{
|
h
,
a
|
h
[
a
]
=
args
[
attributes
.
index
(
a
)];
h
}
end
record
=
where
(
conditions
).
first
unless
record
record
=
@klass
.
new
{
|
r
|
r
.
send
(
:attributes
=
,
attributes_for_create
,
guard_protected_attributes
)
}
yield
(
record
)
if
block_given?
record
.
save
if
match
.
instantiator
==
:create
end
record
end
def
find_one
(
id
)
record
=
where
(
@klass
.
primary_key
=>
id
).
first
unless
record
conditions
=
where_clause
(
', '
)
conditions
=
" [WHERE
#{
conditions
}
]"
if
conditions
.
present?
raise
RecordNotFound
,
"Couldn't find
#{
@klass
.
name
}
with ID=
#{
id
}#{
conditions
}
"
end
record
end
def
find_some
(
ids
)
result
=
where
(
@klass
.
primary_key
=>
ids
).
all
expected_size
=
if
@relation
.
taken
&&
ids
.
size
>
@relation
.
taken
@relation
.
taken
else
ids
.
size
end
# 11 ids with limit 3, offset 9 should give 2 results.
if
@relation
.
skipped
&&
(
ids
.
size
-
@relation
.
skipped
<
expected_size
)
expected_size
=
ids
.
size
-
@relation
.
skipped
end
if
result
.
size
==
expected_size
result
else
conditions
=
where_clause
(
', '
)
conditions
=
" [WHERE
#{
conditions
}
]"
if
conditions
.
present?
error
=
"Couldn't find all
#{
@klass
.
name
.
pluralize
}
with IDs "
error
<<
"(
#{
ids
.
join
(
", "
)
}
)
#{
conditions
}
(found
#{
result
.
size
}
results, but was looking for
#{
expected_size
}
)"
raise
RecordNotFound
,
error
end
end
def
where_clause
(
join_string
=
"
\n\t
AND "
)
@relation
.
send
(
:where_clauses
).
join
(
join_string
)
end
def
reverse_sql_order
(
order_query
)
order_query
.
to_s
.
split
(
/,/
).
each
{
|
s
|
if
s
.
match
(
/\s(asc|ASC)$/
)
s
.
gsub!
(
/\s(asc|ASC)$/
,
' DESC'
)
elsif
s
.
match
(
/\s(desc|DESC)$/
)
s
.
gsub!
(
/\s(desc|DESC)$/
,
' ASC'
)
else
s
.
concat
(
' DESC'
)
end
}.
join
(
','
)
end
end
end
activerecord/lib/active_record/relation
al_calculation
s.rb
→
activerecord/lib/active_record/relation
/calculation_method
s.rb
浏览文件 @
7aabaac0
module
ActiveRecord
module
RelationalCalculation
s
module
CalculationMethod
s
def
count
(
*
args
)
calculate
(
:count
,
*
construct_count_options_from_args
(
*
args
))
...
...
activerecord/lib/active_record/relation/finder_methods.rb
0 → 100644
浏览文件 @
7aabaac0
module
ActiveRecord
module
FinderMethods
def
find
(
*
ids
,
&
block
)
return
to_a
.
find
(
&
block
)
if
block_given?
expects_array
=
ids
.
first
.
kind_of?
(
Array
)
return
ids
.
first
if
expects_array
&&
ids
.
first
.
empty?
ids
=
ids
.
flatten
.
compact
.
uniq
case
ids
.
size
when
0
raise
RecordNotFound
,
"Couldn't find
#{
@klass
.
name
}
without an ID"
when
1
result
=
find_one
(
ids
.
first
)
expects_array
?
[
result
]
:
result
else
find_some
(
ids
)
end
end
def
exists?
(
id
=
nil
)
relation
=
select
(
"
#{
@klass
.
quoted_table_name
}
.
#{
@klass
.
primary_key
}
"
).
limit
(
1
)
relation
=
relation
.
where
(
@klass
.
primary_key
=>
id
)
if
id
relation
.
first
?
true
:
false
end
def
first
if
loaded?
@records
.
first
else
@first
||=
limit
(
1
).
to_a
[
0
]
end
end
def
last
if
loaded?
@records
.
last
else
@last
||=
reverse_order
.
limit
(
1
).
to_a
[
0
]
end
end
protected
def
find_by_attributes
(
match
,
attributes
,
*
args
)
conditions
=
attributes
.
inject
({})
{
|
h
,
a
|
h
[
a
]
=
args
[
attributes
.
index
(
a
)];
h
}
result
=
where
(
conditions
).
send
(
match
.
finder
)
if
match
.
bang?
&&
result
.
blank?
raise
RecordNotFound
,
"Couldn't find
#{
@klass
.
name
}
with
#{
conditions
.
to_a
.
collect
{
|
p
|
p
.
join
(
' = '
)
}
.join(', ')}"
else
result
end
end
def
find_or_instantiator_by_attributes
(
match
,
attributes
,
*
args
)
guard_protected_attributes
=
false
if
args
[
0
].
is_a?
(
Hash
)
guard_protected_attributes
=
true
attributes_for_create
=
args
[
0
].
with_indifferent_access
conditions
=
attributes_for_create
.
slice
(
*
attributes
).
symbolize_keys
else
attributes_for_create
=
conditions
=
attributes
.
inject
({})
{
|
h
,
a
|
h
[
a
]
=
args
[
attributes
.
index
(
a
)];
h
}
end
record
=
where
(
conditions
).
first
unless
record
record
=
@klass
.
new
{
|
r
|
r
.
send
(
:attributes
=
,
attributes_for_create
,
guard_protected_attributes
)
}
yield
(
record
)
if
block_given?
record
.
save
if
match
.
instantiator
==
:create
end
record
end
def
find_one
(
id
)
record
=
where
(
@klass
.
primary_key
=>
id
).
first
unless
record
conditions
=
where_clause
(
', '
)
conditions
=
" [WHERE
#{
conditions
}
]"
if
conditions
.
present?
raise
RecordNotFound
,
"Couldn't find
#{
@klass
.
name
}
with ID=
#{
id
}#{
conditions
}
"
end
record
end
def
find_some
(
ids
)
result
=
where
(
@klass
.
primary_key
=>
ids
).
all
expected_size
=
if
@relation
.
taken
&&
ids
.
size
>
@relation
.
taken
@relation
.
taken
else
ids
.
size
end
# 11 ids with limit 3, offset 9 should give 2 results.
if
@relation
.
skipped
&&
(
ids
.
size
-
@relation
.
skipped
<
expected_size
)
expected_size
=
ids
.
size
-
@relation
.
skipped
end
if
result
.
size
==
expected_size
result
else
conditions
=
where_clause
(
', '
)
conditions
=
" [WHERE
#{
conditions
}
]"
if
conditions
.
present?
error
=
"Couldn't find all
#{
@klass
.
name
.
pluralize
}
with IDs "
error
<<
"(
#{
ids
.
join
(
", "
)
}
)
#{
conditions
}
(found
#{
result
.
size
}
results, but was looking for
#{
expected_size
}
)"
raise
RecordNotFound
,
error
end
end
end
end
activerecord/lib/active_record/relation/query_methods.rb
0 → 100644
浏览文件 @
7aabaac0
module
ActiveRecord
module
QueryMethods
def
preload
(
*
associations
)
spawn
.
tap
{
|
r
|
r
.
preload_associations
+=
Array
.
wrap
(
associations
)
}
end
def
eager_load
(
*
associations
)
spawn
.
tap
{
|
r
|
r
.
eager_load_associations
+=
Array
.
wrap
(
associations
)
}
end
def
readonly
(
status
=
true
)
spawn
.
tap
{
|
r
|
r
.
readonly
=
status
}
end
def
select
(
selects
)
if
selects
.
present?
relation
=
spawn
(
@relation
.
project
(
selects
))
relation
.
readonly
=
@relation
.
joins
(
relation
).
present?
?
false
:
@readonly
relation
else
spawn
end
end
def
from
(
from
)
from
.
present?
?
spawn
(
@relation
.
from
(
from
))
:
spawn
end
def
having
(
*
args
)
return
spawn
if
args
.
blank?
if
[
String
,
Hash
,
Array
].
include?
(
args
.
first
.
class
)
havings
=
@klass
.
send
(
:merge_conditions
,
args
.
size
>
1
?
Array
.
wrap
(
args
)
:
args
.
first
)
else
havings
=
args
.
first
end
spawn
(
@relation
.
having
(
havings
))
end
def
group
(
groups
)
groups
.
present?
?
spawn
(
@relation
.
group
(
groups
))
:
spawn
end
def
order
(
orders
)
orders
.
present?
?
spawn
(
@relation
.
order
(
orders
))
:
spawn
end
def
lock
(
locks
=
true
)
case
locks
when
String
spawn
(
@relation
.
lock
(
locks
))
when
TrueClass
,
NilClass
spawn
(
@relation
.
lock
)
else
spawn
end
end
def
reverse_order
relation
=
spawn
relation
.
instance_variable_set
(
:@orders
,
nil
)
order_clause
=
@relation
.
send
(
:order_clauses
).
join
(
', '
)
if
order_clause
.
present?
relation
.
order
(
reverse_sql_order
(
order_clause
))
else
relation
.
order
(
"
#{
@klass
.
table_name
}
.
#{
@klass
.
primary_key
}
DESC"
)
end
end
def
limit
(
limits
)
limits
.
present?
?
spawn
(
@relation
.
take
(
limits
))
:
spawn
end
def
offset
(
offsets
)
offsets
.
present?
?
spawn
(
@relation
.
skip
(
offsets
))
:
spawn
end
def
on
(
join
)
spawn
(
@relation
.
on
(
join
))
end
def
joins
(
join
,
join_type
=
nil
)
return
spawn
if
join
.
blank?
join_relation
=
case
join
when
String
@relation
.
join
(
join
)
when
Hash
,
Array
,
Symbol
if
@klass
.
send
(
:array_of_strings?
,
join
)
@relation
.
join
(
join
.
join
(
' '
))
else
@relation
.
join
(
@klass
.
send
(
:build_association_joins
,
join
))
end
else
@relation
.
join
(
join
,
join_type
)
end
spawn
(
join_relation
).
tap
{
|
r
|
r
.
readonly
=
true
}
end
def
where
(
*
args
)
return
spawn
if
args
.
blank?
if
[
String
,
Hash
,
Array
].
include?
(
args
.
first
.
class
)
conditions
=
@klass
.
send
(
:merge_conditions
,
args
.
size
>
1
?
Array
.
wrap
(
args
)
:
args
.
first
)
conditions
=
Arel
::
SqlLiteral
.
new
(
conditions
)
if
conditions
else
conditions
=
args
.
first
end
spawn
(
@relation
.
where
(
conditions
))
end
private
def
reverse_sql_order
(
order_query
)
order_query
.
to_s
.
split
(
/,/
).
each
{
|
s
|
if
s
.
match
(
/\s(asc|ASC)$/
)
s
.
gsub!
(
/\s(asc|ASC)$/
,
' DESC'
)
elsif
s
.
match
(
/\s(desc|DESC)$/
)
s
.
gsub!
(
/\s(desc|DESC)$/
,
' ASC'
)
else
s
.
concat
(
' DESC'
)
end
}.
join
(
','
)
end
end
end
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录