Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
张重言
rails
提交
25ca21ae
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,发现更多精彩内容 >>
提交
25ca21ae
编写于
10月 04, 2008
作者:
P
Pratik Naik
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Introduce ActiveRecord::Reflection::ThroughReflection to simplify hm:t reflection logic
上级
95e1cf48
变更
2
隐藏空白更改
内联
并排
Showing
2 changed file
with
70 addition
and
53 deletion
+70
-53
activerecord/lib/active_record/reflection.rb
activerecord/lib/active_record/reflection.rb
+66
-53
activerecord/test/cases/reflection_test.rb
activerecord/test/cases/reflection_test.rb
+4
-0
未找到文件。
activerecord/lib/active_record/reflection.rb
浏览文件 @
25ca21ae
...
...
@@ -13,14 +13,15 @@ module ClassMethods
def
create_reflection
(
macro
,
name
,
options
,
active_record
)
case
macro
when
:has_many
,
:belongs_to
,
:has_one
,
:has_and_belongs_to_many
reflection
=
AssociationReflection
.
new
(
macro
,
name
,
options
,
active_record
)
klass
=
options
[
:through
]
?
ThroughReflection
:
AssociationReflection
reflection
=
klass
.
new
(
macro
,
name
,
options
,
active_record
)
when
:composed_of
reflection
=
AggregateReflection
.
new
(
macro
,
name
,
options
,
active_record
)
end
write_inheritable_hash
:reflections
,
name
=>
reflection
reflection
end
# Returns a hash containing all AssociationReflection objects for the current class
# Example:
#
...
...
@@ -30,7 +31,7 @@ def create_reflection(macro, name, options, active_record)
def
reflections
read_inheritable_attribute
(
:reflections
)
||
write_inheritable_attribute
(
:reflections
,
{})
end
# Returns an array of AggregateReflection objects for all the aggregations in the class.
def
reflect_on_all_aggregations
reflections
.
values
.
select
{
|
reflection
|
reflection
.
is_a?
(
AggregateReflection
)
}
...
...
@@ -192,6 +193,49 @@ def counter_cache_column
end
end
def
check_validity!
end
def
through_reflection
false
end
def
source_reflection
nil
end
private
def
derive_class_name
class_name
=
name
.
to_s
.
camelize
class_name
=
class_name
.
singularize
if
[
:has_many
,
:has_and_belongs_to_many
].
include?
(
macro
)
class_name
end
def
derive_primary_key_name
if
macro
==
:belongs_to
"
#{
name
}
_id"
elsif
options
[
:as
]
"
#{
options
[
:as
]
}
_id"
else
active_record
.
name
.
foreign_key
end
end
end
# Holds all the meta-data about a :through association as it was specified in the Active Record class.
class
ThroughReflection
<
AssociationReflection
#:nodoc:
# Gets the source of the through reflection. It checks both a singularized and pluralized form for <tt>:belongs_to</tt> or <tt>:has_many</tt>.
# (The <tt>:tags</tt> association on Tagging below.)
#
# class Post < ActiveRecord::Base
# has_many :taggings
# has_many :tags, :through => :taggings
# end
#
def
source_reflection
@source_reflection
||=
source_reflection_names
.
collect
{
|
name
|
through_reflection
.
klass
.
reflect_on_association
(
name
)
}.
compact
.
first
end
# Returns the AssociationReflection object specified in the <tt>:through</tt> option
# of a HasManyThrough or HasOneThrough association. Example:
#
...
...
@@ -204,7 +248,7 @@ def counter_cache_column
# taggings_reflection = tags_reflection.through_reflection
#
def
through_reflection
@through_reflection
||=
options
[
:through
]
?
active_record
.
reflect_on_association
(
options
[
:through
])
:
false
@through_reflection
||=
active_record
.
reflect_on_association
(
options
[
:through
])
end
# Gets an array of possible <tt>:through</tt> source reflection names:
...
...
@@ -215,63 +259,32 @@ def source_reflection_names
@source_reflection_names
||=
(
options
[
:source
]
?
[
options
[
:source
]]
:
[
name
.
to_s
.
singularize
,
name
]).
collect
{
|
n
|
n
.
to_sym
}
end
# Gets the source of the through reflection. It checks both a singularized and pluralized form for <tt>:belongs_to</tt> or <tt>:has_many</tt>.
# (The <tt>:tags</tt> association on Tagging below.)
#
# class Post < ActiveRecord::Base
# has_many :taggings
# has_many :tags, :through => :taggings
# end
#
def
source_reflection
return
nil
unless
through_reflection
@source_reflection
||=
source_reflection_names
.
collect
{
|
name
|
through_reflection
.
klass
.
reflect_on_association
(
name
)
}.
compact
.
first
end
def
check_validity!
if
options
[
:through
]
if
through_reflection
.
nil?
raise
HasManyThroughAssociationNotFoundError
.
new
(
active_record
.
name
,
self
)
end
if
source_reflection
.
nil?
raise
HasManyThroughSourceAssociationNotFoundError
.
new
(
self
)
end
if
through_reflection
.
nil?
raise
HasManyThroughAssociationNotFoundError
.
new
(
active_record
.
name
,
self
)
end
if
options
[
:source_type
]
&&
source_reflection
.
options
[
:polymorphic
].
nil?
raise
HasManyThroughAssociationPointlessSourceTypeError
.
new
(
active_record
.
name
,
self
,
source_reflection
)
end
if
source_reflection
.
options
[
:polymorphic
]
&&
options
[
:source_type
].
nil?
raise
HasManyThroughAssociationPolymorphicError
.
new
(
active_record
.
name
,
self
,
source_reflection
)
end
unless
[
:belongs_to
,
:has_many
].
include?
(
source_reflection
.
macro
)
&&
source_reflection
.
options
[
:through
].
nil?
raise
HasManyThroughSourceAssociationMacroError
.
new
(
self
)
end
if
source_reflection
.
nil?
raise
HasManyThroughSourceAssociationNotFoundError
.
new
(
self
)
end
if
options
[
:source_type
]
&&
source_reflection
.
options
[
:polymorphic
].
nil?
raise
HasManyThroughAssociationPointlessSourceTypeError
.
new
(
active_record
.
name
,
self
,
source_reflection
)
end
if
source_reflection
.
options
[
:polymorphic
]
&&
options
[
:source_type
].
nil?
raise
HasManyThroughAssociationPolymorphicError
.
new
(
active_record
.
name
,
self
,
source_reflection
)
end
unless
[
:belongs_to
,
:has_many
].
include?
(
source_reflection
.
macro
)
&&
source_reflection
.
options
[
:through
].
nil?
raise
HasManyThroughSourceAssociationMacroError
.
new
(
self
)
end
end
private
def
derive_class_name
# get the class_name of the belongs_to association of the through reflection
if
through_reflection
options
[
:source_type
]
||
source_reflection
.
class_name
else
class_name
=
name
.
to_s
.
camelize
class_name
=
class_name
.
singularize
if
[
:has_many
,
:has_and_belongs_to_many
].
include?
(
macro
)
class_name
end
end
def
derive_primary_key_name
if
macro
==
:belongs_to
"
#{
name
}
_id"
elsif
options
[
:as
]
"
#{
options
[
:as
]
}
_id"
else
active_record
.
name
.
foreign_key
end
options
[
:source_type
]
||
source_reflection
.
class_name
end
end
end
...
...
activerecord/test/cases/reflection_test.rb
浏览文件 @
25ca21ae
...
...
@@ -170,6 +170,10 @@ def test_reflection_should_not_raise_error_when_compared_to_other_object
assert_nothing_raised
{
Firm
.
reflections
[
:clients
]
==
Object
.
new
}
end
def
test_has_many_through_reflection
assert_kind_of
ActiveRecord
::
Reflection
::
ThroughReflection
,
Subscriber
.
reflect_on_association
(
:books
)
end
private
def
assert_reflection
(
klass
,
association
,
options
)
assert
reflection
=
klass
.
reflect_on_association
(
association
)
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录