Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
张重言
rails
提交
5a54bffe
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,发现更多精彩内容 >>
提交
5a54bffe
编写于
6月 22, 2012
作者:
J
Jon Leighton
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Allow associations to take a lambda which builds the scope
上级
4b4a8551
变更
9
隐藏空白更改
内联
并排
Showing
9 changed file
with
69 addition
and
48 deletion
+69
-48
activerecord/lib/active_record/associations.rb
activerecord/lib/active_record/associations.rb
+8
-8
activerecord/lib/active_record/associations/association.rb
activerecord/lib/active_record/associations/association.rb
+5
-1
activerecord/lib/active_record/associations/builder/association.rb
...ord/lib/active_record/associations/builder/association.rb
+15
-6
activerecord/lib/active_record/associations/builder/collection_association.rb
...ive_record/associations/builder/collection_association.rb
+2
-6
activerecord/lib/active_record/reflection.rb
activerecord/lib/active_record/reflection.rb
+7
-4
activerecord/test/cases/associations/extension_test.rb
activerecord/test/cases/associations/extension_test.rb
+1
-1
activerecord/test/cases/associations/has_many_associations_test.rb
...ord/test/cases/associations/has_many_associations_test.rb
+7
-0
activerecord/test/cases/reflection_test.rb
activerecord/test/cases/reflection_test.rb
+22
-22
activerecord/test/models/author.rb
activerecord/test/models/author.rb
+2
-0
未找到文件。
activerecord/lib/active_record/associations.rb
浏览文件 @
5a54bffe
...
...
@@ -1192,8 +1192,8 @@ module ClassMethods
# ORDER BY p.first_name
# }
# }
def
has_many
(
name
,
options
=
{}
,
&
extension
)
Builder
::
HasMany
.
build
(
self
,
name
,
options
,
&
extension
)
def
has_many
(
name
,
scope
=
{},
options
=
nil
,
&
extension
)
Builder
::
HasMany
.
build
(
self
,
name
,
scope
,
options
,
&
extension
)
end
# Specifies a one-to-one association with another class. This method should only be used
...
...
@@ -1308,8 +1308,8 @@ def has_many(name, options = {}, &extension)
# has_one :boss, :readonly => :true
# has_one :club, :through => :membership
# has_one :primary_address, :through => :addressables, :conditions => ["addressable.primary = ?", true], :source => :addressable
def
has_one
(
name
,
options
=
{}
)
Builder
::
HasOne
.
build
(
self
,
name
,
options
)
def
has_one
(
name
,
scope
=
{},
options
=
nil
)
Builder
::
HasOne
.
build
(
self
,
name
,
scope
,
options
)
end
# Specifies a one-to-one association with another class. This method should only be used
...
...
@@ -1431,8 +1431,8 @@ def has_one(name, options = {})
# belongs_to :post, :counter_cache => true
# belongs_to :company, :touch => true
# belongs_to :company, :touch => :employees_last_updated_at
def
belongs_to
(
name
,
options
=
{}
)
Builder
::
BelongsTo
.
build
(
self
,
name
,
options
)
def
belongs_to
(
name
,
scope
=
{},
options
=
nil
)
Builder
::
BelongsTo
.
build
(
self
,
name
,
scope
,
options
)
end
# Specifies a many-to-many relationship with another class. This associates two classes via an
...
...
@@ -1605,8 +1605,8 @@ def belongs_to(name, options = {})
# has_and_belongs_to_many :categories, :readonly => true
# has_and_belongs_to_many :active_projects, :join_table => 'developers_projects', :delete_sql =>
# proc { |record| "DELETE FROM developers_projects WHERE active=1 AND developer_id = #{id} AND project_id = #{record.id}" }
def
has_and_belongs_to_many
(
name
,
options
=
{}
,
&
extension
)
Builder
::
HasAndBelongsToMany
.
build
(
self
,
name
,
options
,
&
extension
)
def
has_and_belongs_to_many
(
name
,
scope
=
{},
options
=
nil
,
&
extension
)
Builder
::
HasAndBelongsToMany
.
build
(
self
,
name
,
scope
,
options
,
&
extension
)
end
end
end
...
...
activerecord/lib/active_record/associations/association.rb
浏览文件 @
5a54bffe
...
...
@@ -82,7 +82,7 @@ def target=(target)
end
def
scoped
target_scope
.
merge
(
association_scope
)
target_scope
.
merge
(
association_scope
)
.
merge
(
reflection_scope
)
end
# The scope for this association.
...
...
@@ -101,6 +101,10 @@ def reset_scope
@association_scope
=
nil
end
def
reflection_scope
reflection
.
scope
&&
klass
.
instance_exec
(
&
reflection
.
scope
)
end
# Set the inverse association, if possible
def
set_inverse_instance
(
record
)
if
record
&&
invertible_for?
(
record
)
...
...
activerecord/lib/active_record/associations/builder/association.rb
浏览文件 @
5a54bffe
...
...
@@ -6,14 +6,23 @@ class Association #:nodoc:
# Set by subclasses
class_attribute
:macro
attr_reader
:model
,
:name
,
:options
,
:reflection
attr_reader
:model
,
:name
,
:
scope
,
:
options
,
:reflection
def
self
.
build
(
model
,
name
,
options
)
new
(
model
,
name
,
options
).
build
def
self
.
build
(
*
args
,
&
block
)
new
(
*
args
,
&
block
).
build
end
def
initialize
(
model
,
name
,
options
)
@model
,
@name
,
@options
=
model
,
name
,
options
def
initialize
(
model
,
name
,
scope
,
options
)
@model
=
model
@name
=
name
if
options
@scope
=
scope
@options
=
options
else
@scope
=
nil
@options
=
scope
end
end
def
mixin
...
...
@@ -22,7 +31,7 @@ def mixin
def
build
validate_options
reflection
=
model
.
create_reflection
(
self
.
class
.
macro
,
name
,
options
,
model
)
reflection
=
model
.
create_reflection
(
self
.
class
.
macro
,
name
,
scope
,
options
,
model
)
define_accessors
reflection
end
...
...
activerecord/lib/active_record/associations/builder/collection_association.rb
浏览文件 @
5a54bffe
...
...
@@ -9,12 +9,8 @@ class CollectionAssociation < Association #:nodoc:
attr_reader
:block_extension
def
self
.
build
(
model
,
name
,
options
,
&
extension
)
new
(
model
,
name
,
options
,
&
extension
).
build
end
def
initialize
(
model
,
name
,
options
,
&
extension
)
super
(
model
,
name
,
options
)
def
initialize
(
*
args
,
&
extension
)
super
(
*
args
)
@block_extension
=
extension
end
...
...
activerecord/lib/active_record/reflection.rb
浏览文件 @
5a54bffe
...
...
@@ -20,9 +20,9 @@ module Reflection # :nodoc:
# MacroReflection class has info for the AssociationReflection
# class.
module
ClassMethods
def
create_reflection
(
macro
,
name
,
options
,
active_record
)
def
create_reflection
(
macro
,
name
,
scope
,
options
,
active_record
)
klass
=
options
[
:through
]
?
ThroughReflection
:
AssociationReflection
reflection
=
klass
.
new
(
macro
,
name
,
options
,
active_record
)
reflection
=
klass
.
new
(
macro
,
name
,
scope
,
options
,
active_record
)
self
.
reflections
=
self
.
reflections
.
merge
(
name
=>
reflection
)
reflection
...
...
@@ -71,6 +71,8 @@ class MacroReflection
# <tt>has_many :clients</tt> returns <tt>:has_many</tt>
attr_reader
:macro
attr_reader
:scope
# Returns the hash of options used for the macro.
#
# <tt>has_many :clients</tt> returns +{}+
...
...
@@ -80,9 +82,10 @@ class MacroReflection
attr_reader
:plural_name
# :nodoc:
def
initialize
(
macro
,
name
,
options
,
active_record
)
def
initialize
(
macro
,
name
,
scope
,
options
,
active_record
)
@macro
=
macro
@name
=
name
@scope
=
scope
@options
=
options
@active_record
=
active_record
@plural_name
=
active_record
.
pluralize_table_names
?
...
...
@@ -142,7 +145,7 @@ def klass
@klass
||=
active_record
.
send
(
:compute_type
,
class_name
)
end
def
initialize
(
macro
,
name
,
options
,
active_record
)
def
initialize
(
*
args
)
super
@collection
=
[
:has_many
,
:has_and_belongs_to_many
].
include?
(
macro
)
end
...
...
activerecord/test/cases/associations/extension_test.rb
浏览文件 @
5a54bffe
...
...
@@ -70,7 +70,7 @@ def test_proxy_association_after_scoped
private
def
extension_name
(
model
)
builder
=
ActiveRecord
::
Associations
::
Builder
::
HasMany
.
new
(
model
,
:association_name
,
{})
{
}
builder
=
ActiveRecord
::
Associations
::
Builder
::
HasMany
.
new
(
model
,
:association_name
,
nil
,
{})
{
}
builder
.
send
(
:wrap_block_extension
)
builder
.
options
[
:extend
].
first
.
name
end
...
...
activerecord/test/cases/associations/has_many_associations_test.rb
浏览文件 @
5a54bffe
...
...
@@ -1638,4 +1638,11 @@ def test_collection_association_with_private_kernel_method
post
.
taggings_with_delete_all
.
delete_all
end
end
test
"association using a scope block"
do
author
=
authors
(
:david
)
assert
author
.
posts
.
size
>
1
assert_equal
author
.
posts
.
order
(
'posts.id'
).
limit
(
1
),
author
.
posts_with_scope_block
end
end
activerecord/test/cases/reflection_test.rb
浏览文件 @
5a54bffe
...
...
@@ -77,7 +77,7 @@ def test_integer_columns
end
def
test_reflection_klass_for_nested_class_name
reflection
=
MacroReflection
.
new
(
:company
,
nil
,
{
:class_name
=>
'MyApplication::Business::Company'
},
ActiveRecord
::
Base
)
reflection
=
MacroReflection
.
new
(
:company
,
nil
,
nil
,
{
:class_name
=>
'MyApplication::Business::Company'
},
ActiveRecord
::
Base
)
assert_nothing_raised
do
assert_equal
MyApplication
::
Business
::
Company
,
reflection
.
klass
end
...
...
@@ -93,7 +93,7 @@ def test_reflect_on_all_autosave_associations
end
def
test_has_many_reflection
reflection_for_clients
=
AssociationReflection
.
new
(
:has_many
,
:clients
,
{
:order
=>
"id"
,
:dependent
=>
:destroy
},
Firm
)
reflection_for_clients
=
AssociationReflection
.
new
(
:has_many
,
:clients
,
nil
,
{
:order
=>
"id"
,
:dependent
=>
:destroy
},
Firm
)
assert_equal
reflection_for_clients
,
Firm
.
reflect_on_association
(
:clients
)
...
...
@@ -105,7 +105,7 @@ def test_has_many_reflection
end
def
test_has_one_reflection
reflection_for_account
=
AssociationReflection
.
new
(
:has_one
,
:account
,
{
:foreign_key
=>
"firm_id"
,
:dependent
=>
:destroy
},
Firm
)
reflection_for_account
=
AssociationReflection
.
new
(
:has_one
,
:account
,
nil
,
{
:foreign_key
=>
"firm_id"
,
:dependent
=>
:destroy
},
Firm
)
assert_equal
reflection_for_account
,
Firm
.
reflect_on_association
(
:account
)
assert_equal
Account
,
Firm
.
reflect_on_association
(
:account
).
klass
...
...
@@ -230,10 +230,10 @@ def test_association_primary_key
end
def
test_association_primary_key_raises_when_missing_primary_key
reflection
=
ActiveRecord
::
Reflection
::
AssociationReflection
.
new
(
:fuu
,
:edge
,
{},
Author
)
reflection
=
ActiveRecord
::
Reflection
::
AssociationReflection
.
new
(
:fuu
,
:edge
,
nil
,
{},
Author
)
assert_raises
(
ActiveRecord
::
UnknownPrimaryKey
)
{
reflection
.
association_primary_key
}
through
=
ActiveRecord
::
Reflection
::
ThroughReflection
.
new
(
:fuu
,
:edge
,
{},
Author
)
through
=
ActiveRecord
::
Reflection
::
ThroughReflection
.
new
(
:fuu
,
:edge
,
nil
,
{},
Author
)
through
.
stubs
(
:source_reflection
).
returns
(
stub_everything
(
:options
=>
{},
:class_name
=>
'Edge'
))
assert_raises
(
ActiveRecord
::
UnknownPrimaryKey
)
{
through
.
association_primary_key
}
end
...
...
@@ -244,7 +244,7 @@ def test_active_record_primary_key
end
def
test_active_record_primary_key_raises_when_missing_primary_key
reflection
=
ActiveRecord
::
Reflection
::
AssociationReflection
.
new
(
:fuu
,
:author
,
{},
Edge
)
reflection
=
ActiveRecord
::
Reflection
::
AssociationReflection
.
new
(
:fuu
,
:author
,
nil
,
{},
Edge
)
assert_raises
(
ActiveRecord
::
UnknownPrimaryKey
)
{
reflection
.
active_record_primary_key
}
end
...
...
@@ -262,32 +262,32 @@ def test_collection_association
end
def
test_default_association_validation
assert
AssociationReflection
.
new
(
:has_many
,
:clients
,
{},
Firm
).
validate?
assert
AssociationReflection
.
new
(
:has_many
,
:clients
,
nil
,
{},
Firm
).
validate?
assert
!
AssociationReflection
.
new
(
:has_one
,
:client
,
{},
Firm
).
validate?
assert
!
AssociationReflection
.
new
(
:belongs_to
,
:client
,
{},
Firm
).
validate?
assert
!
AssociationReflection
.
new
(
:has_and_belongs_to_many
,
:clients
,
{},
Firm
).
validate?
assert
!
AssociationReflection
.
new
(
:has_one
,
:client
,
nil
,
{},
Firm
).
validate?
assert
!
AssociationReflection
.
new
(
:belongs_to
,
:client
,
nil
,
{},
Firm
).
validate?
assert
!
AssociationReflection
.
new
(
:has_and_belongs_to_many
,
:clients
,
nil
,
{},
Firm
).
validate?
end
def
test_always_validate_association_if_explicit
assert
AssociationReflection
.
new
(
:has_one
,
:client
,
{
:validate
=>
true
},
Firm
).
validate?
assert
AssociationReflection
.
new
(
:belongs_to
,
:client
,
{
:validate
=>
true
},
Firm
).
validate?
assert
AssociationReflection
.
new
(
:has_many
,
:clients
,
{
:validate
=>
true
},
Firm
).
validate?
assert
AssociationReflection
.
new
(
:has_and_belongs_to_many
,
:clients
,
{
:validate
=>
true
},
Firm
).
validate?
assert
AssociationReflection
.
new
(
:has_one
,
:client
,
nil
,
{
:validate
=>
true
},
Firm
).
validate?
assert
AssociationReflection
.
new
(
:belongs_to
,
:client
,
nil
,
{
:validate
=>
true
},
Firm
).
validate?
assert
AssociationReflection
.
new
(
:has_many
,
:clients
,
nil
,
{
:validate
=>
true
},
Firm
).
validate?
assert
AssociationReflection
.
new
(
:has_and_belongs_to_many
,
:clients
,
nil
,
{
:validate
=>
true
},
Firm
).
validate?
end
def
test_validate_association_if_autosave
assert
AssociationReflection
.
new
(
:has_one
,
:client
,
{
:autosave
=>
true
},
Firm
).
validate?
assert
AssociationReflection
.
new
(
:belongs_to
,
:client
,
{
:autosave
=>
true
},
Firm
).
validate?
assert
AssociationReflection
.
new
(
:has_many
,
:clients
,
{
:autosave
=>
true
},
Firm
).
validate?
assert
AssociationReflection
.
new
(
:has_and_belongs_to_many
,
:clients
,
{
:autosave
=>
true
},
Firm
).
validate?
assert
AssociationReflection
.
new
(
:has_one
,
:client
,
nil
,
{
:autosave
=>
true
},
Firm
).
validate?
assert
AssociationReflection
.
new
(
:belongs_to
,
:client
,
nil
,
{
:autosave
=>
true
},
Firm
).
validate?
assert
AssociationReflection
.
new
(
:has_many
,
:clients
,
nil
,
{
:autosave
=>
true
},
Firm
).
validate?
assert
AssociationReflection
.
new
(
:has_and_belongs_to_many
,
:clients
,
nil
,
{
:autosave
=>
true
},
Firm
).
validate?
end
def
test_never_validate_association_if_explicit
assert
!
AssociationReflection
.
new
(
:has_one
,
:client
,
{
:autosave
=>
true
,
:validate
=>
false
},
Firm
).
validate?
assert
!
AssociationReflection
.
new
(
:belongs_to
,
:client
,
{
:autosave
=>
true
,
:validate
=>
false
},
Firm
).
validate?
assert
!
AssociationReflection
.
new
(
:has_many
,
:clients
,
{
:autosave
=>
true
,
:validate
=>
false
},
Firm
).
validate?
assert
!
AssociationReflection
.
new
(
:has_and_belongs_to_many
,
:clients
,
{
:autosave
=>
true
,
:validate
=>
false
},
Firm
).
validate?
assert
!
AssociationReflection
.
new
(
:has_one
,
:client
,
nil
,
{
:autosave
=>
true
,
:validate
=>
false
},
Firm
).
validate?
assert
!
AssociationReflection
.
new
(
:belongs_to
,
:client
,
nil
,
{
:autosave
=>
true
,
:validate
=>
false
},
Firm
).
validate?
assert
!
AssociationReflection
.
new
(
:has_many
,
:clients
,
nil
,
{
:autosave
=>
true
,
:validate
=>
false
},
Firm
).
validate?
assert
!
AssociationReflection
.
new
(
:has_and_belongs_to_many
,
:clients
,
nil
,
{
:autosave
=>
true
,
:validate
=>
false
},
Firm
).
validate?
end
def
test_foreign_key
...
...
activerecord/test/models/author.rb
浏览文件 @
5a54bffe
...
...
@@ -26,6 +26,8 @@ def testing_proxy_target
has_many
:comments_with_order_and_conditions
,
:through
=>
:posts
,
:source
=>
:comments
,
:order
=>
'comments.body'
,
:conditions
=>
"comments.body like 'Thank%'"
has_many
:comments_with_include
,
:through
=>
:posts
,
:source
=>
:comments
,
:include
=>
:post
has_many
:posts_with_scope_block
,
->
{
order
(
'posts.id'
).
limit
(
1
)
},
:class_name
=>
"Post"
has_many
:first_posts
has_many
:comments_on_first_posts
,
:through
=>
:first_posts
,
:source
=>
:comments
,
:order
=>
'posts.id desc, comments.id asc'
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录