Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
张重言
rails
提交
c3aa2bcd
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 搜索 >>
提交
c3aa2bcd
编写于
3月 10, 2009
作者:
M
Manfred Stienstra
提交者:
Pratik Naik
3月 10, 2009
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Ensure nested with_scope merges conditions inside out [#2193 state:resolved]
Signed-off-by:
N
Pratik Naik
<
pratiknaik@gmail.com
>
上级
8272630c
变更
4
隐藏空白更改
内联
并排
Showing
4 changed file
with
57 addition
and
26 deletion
+57
-26
activerecord/lib/active_record/base.rb
activerecord/lib/active_record/base.rb
+8
-11
activerecord/lib/active_record/named_scope.rb
activerecord/lib/active_record/named_scope.rb
+2
-2
activerecord/test/cases/method_scoping_test.rb
activerecord/test/cases/method_scoping_test.rb
+33
-5
activerecord/test/cases/named_scope_test.rb
activerecord/test/cases/named_scope_test.rb
+14
-8
未找到文件。
activerecord/lib/active_record/base.rb
浏览文件 @
c3aa2bcd
...
...
@@ -416,7 +416,7 @@ def self.reset_subclasses #:nodoc:
end
@@subclasses
=
{}
##
# :singleton-method:
# Contains the database configuration - as is typically stored in config/database.yml -
...
...
@@ -661,7 +661,6 @@ def find_by_sql(sql)
connection
.
select_all
(
sanitize_sql
(
sql
),
"
#{
name
}
Load"
).
collect!
{
|
record
|
instantiate
(
record
)
}
end
# Returns true if a record exists in the table that matches the +id+ or
# conditions given, or false otherwise. The argument can take five forms:
#
...
...
@@ -1003,7 +1002,6 @@ def decrement_counter(counter_name, id)
update_counters
(
id
,
counter_name
=>
-
1
)
end
# Attributes named in this macro are protected from mass-assignment,
# such as <tt>new(attributes)</tt>,
# <tt>update_attributes(attributes)</tt>, or
...
...
@@ -1104,7 +1102,6 @@ def serialized_attributes
read_inheritable_attribute
(
:attr_serialized
)
or
write_inheritable_attribute
(
:attr_serialized
,
{})
end
# Guesses the table name (in forced lower-case) based on the name of the class in the inheritance hierarchy descending
# directly from ActiveRecord::Base. So if the hierarchy looks like: Reply < Message < ActiveRecord::Base, then Message is used
# to guess the table name even when called on Reply. The rules used to do the guess are handled by the Inflector class
...
...
@@ -1417,7 +1414,6 @@ def inspect
end
end
def
quote_value
(
value
,
column
=
nil
)
#:nodoc:
connection
.
quote
(
value
,
column
)
end
...
...
@@ -1486,7 +1482,7 @@ def respond_to?(method_id, include_private = false)
elsif
match
=
DynamicScopeMatch
.
match
(
method_id
)
return
true
if
all_attributes_exists?
(
match
.
attribute_names
)
end
super
end
...
...
@@ -2014,7 +2010,6 @@ def expand_id_conditions(id_or_conditions)
end
end
# Defines an "attribute" method (like +inheritance_column+ or
# +table_name+). A new (class) method will be created with the
# given name. If a value is specified, the new method will
...
...
@@ -2111,7 +2106,7 @@ def with_scope(method_scoping = {}, action = :merge, &block)
end
# Merge scopings
if
action
==
:merge
&&
current_scoped_methods
if
[
:merge
,
:reverse_merge
].
include?
(
action
)
&&
current_scoped_methods
method_scoping
=
current_scoped_methods
.
inject
(
method_scoping
)
do
|
hash
,
(
method
,
params
)
|
case
hash
[
method
]
when
Hash
...
...
@@ -2133,7 +2128,11 @@ def with_scope(method_scoping = {}, action = :merge, &block)
end
end
else
hash
[
method
]
=
hash
[
method
].
merge
(
params
)
if
action
==
:reverse_merge
hash
[
method
]
=
hash
[
method
].
merge
(
params
)
else
hash
[
method
]
=
params
.
merge
(
hash
[
method
])
end
end
else
hash
[
method
]
=
params
...
...
@@ -2143,7 +2142,6 @@ def with_scope(method_scoping = {}, action = :merge, &block)
end
self
.
scoped_methods
<<
method_scoping
begin
yield
ensure
...
...
@@ -2749,7 +2747,6 @@ def attributes=(new_attributes, guard_protected_attributes = true)
assign_multiparameter_attributes
(
multi_parameter_attributes
)
end
# Returns a hash of all the attributes with their names as keys and the values of the attributes as values.
def
attributes
self
.
attribute_names
.
inject
({})
do
|
attrs
,
name
|
...
...
activerecord/lib/active_record/named_scope.rb
浏览文件 @
c3aa2bcd
...
...
@@ -104,7 +104,7 @@ def named_scope(name, options = {}, &block)
end
end
end
class
Scope
attr_reader
:proxy_scope
,
:proxy_options
,
:current_scoped_methods_when_defined
NON_DELEGATE_METHODS
=
%w(nil? send object_id class extend find size count sum average maximum minimum paginate first last empty? any? respond_to?)
.
to_set
...
...
@@ -175,7 +175,7 @@ def method_missing(method, *args, &block)
if
scopes
.
include?
(
method
)
scopes
[
method
].
call
(
self
,
*
args
)
else
with_scope
:find
=>
proxy_options
,
:create
=>
proxy_options
[
:conditions
].
is_a?
(
Hash
)
?
proxy_options
[
:conditions
]
:
{}
do
with_scope
({
:find
=>
proxy_options
,
:create
=>
proxy_options
[
:conditions
].
is_a?
(
Hash
)
?
proxy_options
[
:conditions
]
:
{}},
:reverse_merge
)
do
method
=
:new
if
method
==
:build
if
current_scoped_methods_when_defined
with_scope
current_scoped_methods_when_defined
do
...
...
activerecord/test/cases/method_scoping_test.rb
浏览文件 @
c3aa2bcd
...
...
@@ -262,6 +262,15 @@ def test_merge_options
end
end
def
test_merge_inner_scope_has_priority
Developer
.
with_scope
(
:find
=>
{
:limit
=>
5
})
do
Developer
.
with_scope
(
:find
=>
{
:limit
=>
10
})
do
merged_option
=
Developer
.
instance_eval
(
'current_scoped_methods'
)[
:find
]
assert_equal
({
:limit
=>
10
},
merged_option
)
end
end
end
def
test_replace_options
Developer
.
with_scope
(
:find
=>
{
:conditions
=>
"name = 'David'"
})
do
Developer
.
with_exclusive_scope
(
:find
=>
{
:conditions
=>
"name = 'Jamis'"
})
do
...
...
@@ -400,6 +409,29 @@ def test_merged_scoped_find_combines_and_sanitizes_conditions
end
end
def
test_nested_scoped_create
comment
=
nil
Comment
.
with_scope
(
:create
=>
{
:post_id
=>
1
})
do
Comment
.
with_scope
(
:create
=>
{
:post_id
=>
2
})
do
assert_equal
({
:post_id
=>
2
},
Comment
.
send
(
:current_scoped_methods
)[
:create
])
comment
=
Comment
.
create
:body
=>
"Hey guys, nested scopes are broken. Please fix!"
end
end
assert_equal
2
,
comment
.
post_id
end
def
test_nested_exclusive_scope_for_create
comment
=
nil
Comment
.
with_scope
(
:create
=>
{
:body
=>
"Hey guys, nested scopes are broken. Please fix!"
})
do
Comment
.
with_exclusive_scope
(
:create
=>
{
:post_id
=>
1
})
do
assert_equal
({
:post_id
=>
1
},
Comment
.
send
(
:current_scoped_methods
)[
:create
])
comment
=
Comment
.
create
:body
=>
"Hey guys"
end
end
assert_equal
1
,
comment
.
post_id
assert_equal
'Hey guys'
,
comment
.
body
end
def
test_merged_scoped_find_on_blank_conditions
[
nil
,
" "
,
[],
{}].
each
do
|
blank
|
Developer
.
with_scope
(
:find
=>
{
:conditions
=>
blank
})
do
...
...
@@ -523,7 +555,6 @@ def test_nested_scope
end
end
class
HasAndBelongsToManyScopingTest
<
ActiveRecord
::
TestCase
fixtures
:posts
,
:categories
,
:categories_posts
...
...
@@ -549,7 +580,6 @@ def test_nested_scope
end
end
class
DefaultScopingTest
<
ActiveRecord
::
TestCase
fixtures
:developers
...
...
@@ -577,7 +607,7 @@ def test_default_scoping_with_inheritance
# Scopes added on children should append to parent scope
expected_klass_scope
=
[{
:create
=>
{},
:find
=>
{
:order
=>
'salary DESC'
}},
{
:create
=>
{},
:find
=>
{}
}]
assert_equal
expected_klass_scope
,
klass
.
send
(
:scoped_methods
)
# Parent should still have the original scope
assert_equal
scope
,
DeveloperOrderedBySalary
.
send
(
:scoped_methods
)
end
...
...
@@ -620,7 +650,6 @@ def test_overwriting_default_scope
=begin
# We disabled the scoping for has_one and belongs_to as we can't think of a proper use case
class BelongsToScopingTest< ActiveRecord::TestCase
fixtures :comments, :posts
...
...
@@ -640,7 +669,6 @@ def test_forwarding_to_dynamic_finders
end
class HasOneScopingTest< ActiveRecord::TestCase
fixtures :comments, :posts
...
...
activerecord/test/cases/named_scope_test.rb
浏览文件 @
c3aa2bcd
...
...
@@ -247,7 +247,7 @@ def test_should_create_with_bang_with_proxy_options
topic
=
Topic
.
approved
.
create!
({})
assert
topic
.
approved
end
def
test_should_build_with_proxy_options_chained
topic
=
Topic
.
approved
.
by_lifo
.
build
({})
assert
topic
.
approved
...
...
@@ -287,15 +287,21 @@ def test_chaining_with_duplicate_joins
assert_equal
post
.
comments
.
size
,
Post
.
scoped
(
:joins
=>
join
).
scoped
(
:joins
=>
join
,
:conditions
=>
"posts.id =
#{
post
.
id
}
"
).
size
end
def
test_chanining_should_use_latest_conditions_when_creating
post1
=
Topic
.
rejected
.
approved
.
new
assert
post1
.
approved?
def
test_chaining_should_use_latest_conditions_when_creating
post
=
Topic
.
rejected
.
new
assert
!
post
.
approved?
post
=
Topic
.
rejected
.
approved
.
new
assert
post
.
approved?
post2
=
Topic
.
approved
.
rejected
.
new
assert
!
post2
.
approved?
post
=
Topic
.
approved
.
rejected
.
new
assert
!
post
.
approved?
post
=
Topic
.
approved
.
rejected
.
approved
.
new
assert
post
.
approved?
end
def
test_cha
n
ining_should_use_latest_conditions_when_searching
def
test_chaining_should_use_latest_conditions_when_searching
# Normal hash conditions
assert_equal
Topic
.
all
(
:conditions
=>
{
:approved
=>
true
}),
Topic
.
rejected
.
approved
.
all
assert_equal
Topic
.
all
(
:conditions
=>
{
:approved
=>
false
}),
Topic
.
approved
.
rejected
.
all
...
...
@@ -306,7 +312,7 @@ def test_chanining_should_use_latest_conditions_when_searching
# Nested hash conditions with different keys
assert_equal
[
posts
(
:sti_comments
)],
Post
.
with_special_comments
.
with_post
(
4
).
all
.
uniq
end
def
test_methods_invoked_within_scopes_should_respect_scope
assert_equal
[],
Topic
.
approved
.
by_rejected_ids
.
proxy_options
[
:conditions
][
:id
]
end
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录