Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
张重言
rails
提交
e5949135
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 搜索 >>
提交
e5949135
编写于
4月 28, 2011
作者:
J
José Valim
浏览文件
操作
浏览文件
下载
差异文件
Merge remote branch 'myron/am_disabling_fix_memory_leaks'
上级
fc343d26
7db7aa50
变更
3
隐藏空白更改
内联
并排
Showing
3 changed file
with
155 addition
and
56 deletion
+155
-56
activemodel/lib/active_model/observer_array.rb
activemodel/lib/active_model/observer_array.rb
+40
-34
activemodel/lib/active_model/observing.rb
activemodel/lib/active_model/observing.rb
+16
-21
activemodel/test/cases/observer_array_test.rb
activemodel/test/cases/observer_array_test.rb
+99
-1
未找到文件。
activemodel/lib/active_model/observer_array.rb
浏览文件 @
e5949135
...
...
@@ -4,42 +4,16 @@ module ActiveModel
# Stores the enabled/disabled state of individual observers for
# a particular model classes.
class
ObserverArray
<
Array
INSTANCES
=
Hash
.
new
do
|
hash
,
model_class
|
hash
[
model_class
]
=
new
(
model_class
)
end
def
self
.
for
(
model_class
)
return
nil
unless
model_class
<
ActiveModel
::
Observing
INSTANCES
[
model_class
]
end
# returns false if:
# - the ObserverArray for the given model's class has the given observer
# in its disabled_observers set.
# - or that is the case at any level of the model's superclass chain.
def
self
.
observer_enabled?
(
observer
,
model
)
klass
=
model
.
class
observer_class
=
observer
.
class
loop
do
break
unless
array
=
self
.
for
(
klass
)
return
false
if
array
.
disabled_observers
.
include?
(
observer_class
)
klass
=
klass
.
superclass
end
true
# observers are enabled by default
end
def
disabled_observers
@disabled_observers
||=
Set
.
new
end
attr_reader
:model_class
def
initialize
(
model_class
,
*
args
)
@model_class
=
model_class
super
(
*
args
)
end
def
disabled_for?
(
observer
)
disabled_observers
.
include?
(
observer
.
class
)
end
def
disable
(
*
observers
,
&
block
)
set_enablement
(
false
,
observers
,
&
block
)
end
...
...
@@ -48,7 +22,11 @@ def enable(*observers, &block)
set_enablement
(
true
,
observers
,
&
block
)
end
private
protected
def
disabled_observers
@disabled_observers
||=
Set
.
new
end
def
observer_class_for
(
observer
)
return
observer
if
observer
.
is_a?
(
Class
)
...
...
@@ -61,13 +39,37 @@ def observer_class_for(observer)
end
end
def
start_transaction
disabled_observer_stack
.
push
(
disabled_observers
.
dup
)
each_subclass_array
do
|
array
|
array
.
start_transaction
end
end
def
disabled_observer_stack
@disabled_observer_stack
||=
[]
end
def
end_transaction
@disabled_observers
=
disabled_observer_stack
.
pop
each_subclass_array
do
|
array
|
array
.
end_transaction
end
end
def
transaction
orig_disabled_observers
=
disabled_observers
.
dup
start_transaction
begin
yield
ensure
@disabled_observers
=
orig_disabled_observers
end_transaction
end
end
def
each_subclass_array
model_class
.
descendants
.
each
do
|
subclass
|
yield
subclass
.
observers
end
end
...
...
@@ -78,7 +80,7 @@ def set_enablement(enabled, observers)
yield
end
else
observers
=
ActiveModel
::
Observer
.
all_observer
s
if
observers
==
[
:all
]
observers
=
ActiveModel
::
Observer
.
descendant
s
if
observers
==
[
:all
]
observers
.
each
do
|
obs
|
klass
=
observer_class_for
(
obs
)
...
...
@@ -92,6 +94,10 @@ def set_enablement(enabled, observers)
disabled_observers
<<
klass
end
end
each_subclass_array
do
|
array
|
array
.
set_enablement
(
enabled
,
observers
)
end
end
end
end
...
...
activemodel/lib/active_model/observing.rb
浏览文件 @
e5949135
...
...
@@ -5,11 +5,16 @@
require
'active_support/core_ext/module/remove_method'
require
'active_support/core_ext/string/inflections'
require
'active_support/core_ext/enumerable'
require
'active_support/descendants_tracker'
module
ActiveModel
module
Observing
extend
ActiveSupport
::
Concern
included
do
extend
ActiveSupport
::
DescendantsTracker
end
module
ClassMethods
# == Active Model Observers Activation
#
...
...
@@ -37,7 +42,7 @@ def observers=(*values)
# Gets the current observers.
def
observers
@observers
||=
ObserverArray
.
for
(
self
)
@observers
||=
ObserverArray
.
new
(
self
)
end
# Gets the current observer instances.
...
...
@@ -171,6 +176,7 @@ def notify_observers(method)
#
class
Observer
include
Singleton
extend
ActiveSupport
::
DescendantsTracker
class
<<
self
# Attaches the observer to the supplied model classes.
...
...
@@ -203,23 +209,6 @@ def observed_class
nil
end
end
def
subclasses
@subclasses
||=
[]
end
# List of all observer subclasses, sub-subclasses, etc.
# Necessary so we can disable or enable all observers.
def
all_observers
subclasses
.
each_with_object
(
subclasses
.
dup
)
do
|
subclass
,
array
|
array
.
concat
(
subclass
.
all_observers
)
end
end
end
def
self
.
inherited
(
subclass
)
subclasses
<<
subclass
super
end
# Start observing the declared classes and their subclasses.
...
...
@@ -233,9 +222,9 @@ def observed_classes #:nodoc:
# Send observed_method(object) if the method exists.
def
update
(
observed_method
,
object
)
#:nodoc:
if
respond_to?
(
observed_method
)
&&
ObserverArray
.
observer_enabled?
(
self
,
object
)
send
(
observed_method
,
object
)
end
return
unless
respond_to?
(
observed_method
)
return
if
disabled_for?
(
object
)
send
(
observed_method
,
object
)
end
# Special method sent by the observed class when it is inherited.
...
...
@@ -249,5 +238,11 @@ def observed_class_inherited(subclass) #:nodoc:
def
add_observer!
(
klass
)
#:nodoc:
klass
.
add_observer
(
self
)
end
def
disabled_for?
(
object
)
klass
=
object
.
class
return
false
unless
klass
.
respond_to?
(
:observers
)
klass
.
observers
.
disabled_for?
(
self
)
end
end
end
activemodel/test/cases/observer_array_test.rb
浏览文件 @
e5949135
...
...
@@ -38,6 +38,16 @@ def assert_observer_not_notified(model_class, observer_class)
assert_observer_notified
Budget
,
AuditTrail
end
test
"can enable individual observers using a class constant"
do
ORM
.
observers
.
disable
:all
ORM
.
observers
.
enable
AuditTrail
assert_observer_not_notified
Widget
,
WidgetObserver
assert_observer_not_notified
Budget
,
BudgetObserver
assert_observer_notified
Widget
,
AuditTrail
assert_observer_notified
Budget
,
AuditTrail
end
test
"can disable individual observers using a symbol"
do
ORM
.
observers
.
disable
:budget_observer
...
...
@@ -47,6 +57,35 @@ def assert_observer_not_notified(model_class, observer_class)
assert_observer_notified
Budget
,
AuditTrail
end
test
"can enable individual observers using a symbol"
do
ORM
.
observers
.
disable
:all
ORM
.
observers
.
enable
:audit_trail
assert_observer_not_notified
Widget
,
WidgetObserver
assert_observer_not_notified
Budget
,
BudgetObserver
assert_observer_notified
Widget
,
AuditTrail
assert_observer_notified
Budget
,
AuditTrail
end
test
"can disable multiple observers at a time"
do
ORM
.
observers
.
disable
:widget_observer
,
:budget_observer
assert_observer_not_notified
Widget
,
WidgetObserver
assert_observer_not_notified
Budget
,
BudgetObserver
assert_observer_notified
Widget
,
AuditTrail
assert_observer_notified
Budget
,
AuditTrail
end
test
"can enable multiple observers at a time"
do
ORM
.
observers
.
disable
:all
ORM
.
observers
.
enable
:widget_observer
,
:budget_observer
assert_observer_notified
Widget
,
WidgetObserver
assert_observer_notified
Budget
,
BudgetObserver
assert_observer_not_notified
Widget
,
AuditTrail
assert_observer_not_notified
Budget
,
AuditTrail
end
test
"can disable all observers using :all"
do
ORM
.
observers
.
disable
:all
...
...
@@ -56,7 +95,17 @@ def assert_observer_not_notified(model_class, observer_class)
assert_observer_not_notified
Budget
,
AuditTrail
end
test
"can disable observers on individual models without affecting observers on other models"
do
test
"can enable all observers using :all"
do
ORM
.
observers
.
disable
:all
ORM
.
observers
.
enable
:all
assert_observer_notified
Widget
,
WidgetObserver
assert_observer_notified
Budget
,
BudgetObserver
assert_observer_notified
Widget
,
AuditTrail
assert_observer_notified
Budget
,
AuditTrail
end
test
"can disable observers on individual models without affecting those observers on other models"
do
Widget
.
observers
.
disable
:all
assert_observer_not_notified
Widget
,
WidgetObserver
...
...
@@ -65,6 +114,16 @@ def assert_observer_not_notified(model_class, observer_class)
assert_observer_notified
Budget
,
AuditTrail
end
test
"can enable observers on individual models without affecting those observers on other models"
do
ORM
.
observers
.
disable
:all
Budget
.
observers
.
enable
AuditTrail
assert_observer_not_notified
Widget
,
WidgetObserver
assert_observer_not_notified
Budget
,
BudgetObserver
assert_observer_not_notified
Widget
,
AuditTrail
assert_observer_notified
Budget
,
AuditTrail
end
test
"can disable observers for the duration of a block"
do
yielded
=
false
ORM
.
observers
.
disable
:budget_observer
do
...
...
@@ -118,5 +177,44 @@ def assert_observer_not_notified(model_class, observer_class)
ORM
.
observers
.
disable
Widget
end
end
test
"allows #enable at the superclass level to override #disable at the subclass level when called last"
do
Widget
.
observers
.
disable
:all
ORM
.
observers
.
enable
:all
assert_observer_notified
Widget
,
WidgetObserver
assert_observer_notified
Budget
,
BudgetObserver
assert_observer_notified
Widget
,
AuditTrail
assert_observer_notified
Budget
,
AuditTrail
end
test
"allows #disable at the superclass level to override #enable at the subclass level when called last"
do
Budget
.
observers
.
enable
:audit_trail
ORM
.
observers
.
disable
:audit_trail
assert_observer_notified
Widget
,
WidgetObserver
assert_observer_notified
Budget
,
BudgetObserver
assert_observer_not_notified
Widget
,
AuditTrail
assert_observer_not_notified
Budget
,
AuditTrail
end
test
"can use the block form at different levels of the hierarchy"
do
yielded
=
false
Widget
.
observers
.
disable
:all
ORM
.
observers
.
enable
:all
do
yielded
=
true
assert_observer_notified
Widget
,
WidgetObserver
assert_observer_notified
Budget
,
BudgetObserver
assert_observer_notified
Widget
,
AuditTrail
assert_observer_notified
Budget
,
AuditTrail
end
assert
yielded
assert_observer_not_notified
Widget
,
WidgetObserver
assert_observer_notified
Budget
,
BudgetObserver
assert_observer_not_notified
Widget
,
AuditTrail
assert_observer_notified
Budget
,
AuditTrail
end
end
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录