Skip to content
体验新版
项目
组织
正在加载...
登录
切换导航
打开侧边栏
张重言
rails
提交
5b14129d
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 搜索 >>
提交
5b14129d
编写于
12月 23, 2016
作者:
A
Akira Matsuda
浏览文件
操作
浏览文件
下载
电子邮件补丁
差异文件
Privatize unneededly protected methods in Active Record
上级
6c5bbb4b
变更
26
隐藏空白更改
内联
并排
Showing
26 changed file
with
145 addition
and
158 deletion
+145
-158
activerecord/lib/active_record/associations/collection_proxy.rb
...record/lib/active_record/associations/collection_proxy.rb
+3
-5
activerecord/lib/active_record/associations/through_association.rb
...ord/lib/active_record/associations/through_association.rb
+2
-4
activerecord/lib/active_record/attribute.rb
activerecord/lib/active_record/attribute.rb
+12
-11
activerecord/lib/active_record/attribute_methods/primary_key.rb
...record/lib/active_record/attribute_methods/primary_key.rb
+2
-2
activerecord/lib/active_record/attribute_methods/read.rb
activerecord/lib/active_record/attribute_methods/read.rb
+2
-2
activerecord/lib/active_record/attribute_methods/write.rb
activerecord/lib/active_record/attribute_methods/write.rb
+2
-2
activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
...ecord/connection_adapters/abstract/database_statements.rb
+7
-7
activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
..._record/connection_adapters/abstract/schema_statements.rb
+7
-8
activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
...lib/active_record/connection_adapters/abstract_adapter.rb
+13
-13
activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
...tive_record/connection_adapters/abstract_mysql_adapter.rb
+17
-19
activerecord/lib/active_record/connection_adapters/mysql/database_statements.rb
...e_record/connection_adapters/mysql/database_statements.rb
+2
-4
activerecord/lib/active_record/connection_adapters/postgresql/utils.rb
...lib/active_record/connection_adapters/postgresql/utils.rb
+1
-1
activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
...b/active_record/connection_adapters/postgresql_adapter.rb
+2
-4
activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
.../lib/active_record/connection_adapters/sqlite3_adapter.rb
+9
-10
activerecord/lib/active_record/railties/controller_runtime.rb
...verecord/lib/active_record/railties/controller_runtime.rb
+2
-0
activerecord/lib/active_record/relation/delegation.rb
activerecord/lib/active_record/relation/delegation.rb
+1
-1
activerecord/lib/active_record/relation/finder_methods.rb
activerecord/lib/active_record/relation/finder_methods.rb
+10
-12
activerecord/lib/active_record/sanitization.rb
activerecord/lib/active_record/sanitization.rb
+13
-13
activerecord/lib/active_record/scoping/default.rb
activerecord/lib/active_record/scoping/default.rb
+6
-6
activerecord/lib/active_record/scoping/named.rb
activerecord/lib/active_record/scoping/named.rb
+2
-2
activerecord/lib/active_record/store.rb
activerecord/lib/active_record/store.rb
+3
-4
activerecord/lib/active_record/transactions.rb
activerecord/lib/active_record/transactions.rb
+7
-9
activerecord/lib/active_record/validations.rb
activerecord/lib/active_record/validations.rb
+4
-4
activerecord/lib/active_record/validations/uniqueness.rb
activerecord/lib/active_record/validations/uniqueness.rb
+5
-5
activerecord/lib/rails/generators/active_record/migration/migration_generator.rb
...generators/active_record/migration/migration_generator.rb
+5
-4
activerecord/lib/rails/generators/active_record/model/model_generator.rb
...b/rails/generators/active_record/model/model_generator.rb
+6
-6
未找到文件。
activerecord/lib/active_record/associations/collection_proxy.rb
浏览文件 @
5b14129d
...
...
@@ -1126,20 +1126,18 @@ def reset
self
end
pr
otected
pr
ivate
def
find_nth_with_limit
(
index
,
limit
)
def
find_nth_with_limit
(
index
,
limit
)
# :doc:
load_target
if
find_from_target?
super
end
def
find_nth_from_last
(
index
)
def
find_nth_from_last
(
index
)
# :doc:
load_target
if
find_from_target?
super
end
private
def
null_scope?
@association
.
null_scope?
end
...
...
activerecord/lib/active_record/associations/through_association.rb
浏览文件 @
5b14129d
...
...
@@ -4,13 +4,13 @@ module Associations
module
ThroughAssociation
#:nodoc:
delegate
:source_reflection
,
:through_reflection
,
to: :reflection
pr
otected
pr
ivate
# We merge in these scopes for two reasons:
#
# 1. To get the default_scope conditions for any of the other reflections in the chain
# 2. To get the type conditions for any STI models in the chain
def
target_scope
def
target_scope
# :doc:
scope
=
super
reflection
.
chain
.
drop
(
1
).
each
do
|
reflection
|
relation
=
reflection
.
klass
.
all
...
...
@@ -21,8 +21,6 @@ def target_scope
scope
end
private
# Construct attributes for :through pointing to owner and associate. This is used by the
# methods which create and delete records on the association.
#
...
...
activerecord/lib/active_record/attribute.rb
浏览文件 @
5b14129d
...
...
@@ -135,25 +135,26 @@ def encode_with(coder)
attr_reader
:original_attribute
alias_method
:assigned?
,
:original_attribute
def
initialize_dup
(
other
)
def
original_value_for_database
# :doc:
if
assigned?
original_attribute
.
original_value_for_database
else
_original_value_for_database
end
end
private
def
initialize_dup
(
other
)
# :doc:
if
defined?
(
@value
)
&&
@value
.
duplicable?
@value
=
@value
.
dup
end
end
def
changed_from_assignment?
def
changed_from_assignment?
# :doc:
assigned?
&&
type
.
changed?
(
original_value
,
value
,
value_before_type_cast
)
end
def
original_value_for_database
if
assigned?
original_attribute
.
original_value_for_database
else
_original_value_for_database
end
end
def
_original_value_for_database
def
_original_value_for_database
# :doc:
type
.
serialize
(
original_value
)
end
...
...
activerecord/lib/active_record/attribute_methods/primary_key.rb
浏览文件 @
5b14129d
...
...
@@ -50,9 +50,9 @@ def id_in_database
attribute_in_database
(
self
.
class
.
primary_key
)
end
pr
otected
pr
ivate
def
attribute_method?
(
attr_name
)
def
attribute_method?
(
attr_name
)
# :doc:
attr_name
==
"id"
||
super
end
...
...
activerecord/lib/active_record/attribute_methods/read.rb
浏览文件 @
5b14129d
...
...
@@ -4,7 +4,7 @@ module Read
extend
ActiveSupport
::
Concern
module
ClassMethods
pr
otected
pr
ivate
# We want to generate the methods via module_eval rather than
# define_method, because define_method is slower on dispatch.
...
...
@@ -24,7 +24,7 @@ module ClassMethods
# to allocate an object on each call to the attribute method.
# Making it frozen means that it doesn't get duped when used to
# key the @attributes in read_attribute.
def
define_method_attribute
(
name
)
def
define_method_attribute
(
name
)
# :doc:
safe_name
=
name
.
unpack
(
"h*"
.
freeze
).
first
temp_method
=
"__temp__
#{
safe_name
}
"
...
...
activerecord/lib/active_record/attribute_methods/write.rb
浏览文件 @
5b14129d
...
...
@@ -8,9 +8,9 @@ module Write
end
module
ClassMethods
pr
otected
pr
ivate
def
define_method_attribute
=
(
name
)
def
define_method_attribute
=
(
name
)
# :doc:
safe_name
=
name
.
unpack
(
"h*"
.
freeze
).
first
ActiveRecord
::
AttributeMethods
::
AttrNames
.
set_name_cache
safe_name
,
name
...
...
activerecord/lib/active_record/connection_adapters/abstract/database_statements.rb
浏览文件 @
5b14129d
...
...
@@ -360,34 +360,34 @@ def join_to_update(update, select, key) # :nodoc:
end
alias
join_to_delete
join_to_update
pr
otected
pr
ivate
# Returns a subquery for the given key using the join information.
def
subquery_for
(
key
,
select
)
def
subquery_for
(
key
,
select
)
# :doc:
subselect
=
select
.
clone
subselect
.
projections
=
[
key
]
subselect
end
# Returns an ActiveRecord::Result instance.
def
select
(
sql
,
name
=
nil
,
binds
=
[])
def
select
(
sql
,
name
=
nil
,
binds
=
[])
# :doc:
exec_query
(
sql
,
name
,
binds
,
prepare:
false
)
end
def
select_prepared
(
sql
,
name
=
nil
,
binds
=
[])
def
select_prepared
(
sql
,
name
=
nil
,
binds
=
[])
# :doc:
exec_query
(
sql
,
name
,
binds
,
prepare:
true
)
end
def
sql_for_insert
(
sql
,
pk
,
id_value
,
sequence_name
,
binds
)
def
sql_for_insert
(
sql
,
pk
,
id_value
,
sequence_name
,
binds
)
# :doc:
[
sql
,
binds
]
end
def
last_inserted_id
(
result
)
def
last_inserted_id
(
result
)
# :doc:
row
=
result
.
rows
.
first
row
&&
row
.
first
end
def
binds_from_relation
(
relation
,
binds
)
def
binds_from_relation
(
relation
,
binds
)
# :doc:
if
relation
.
is_a?
(
Relation
)
&&
binds
.
empty?
relation
,
binds
=
relation
.
arel
,
relation
.
bound_attributes
end
...
...
activerecord/lib/active_record/connection_adapters/abstract/schema_statements.rb
浏览文件 @
5b14129d
...
...
@@ -1169,9 +1169,9 @@ def change_column_comment(table_name, column_name, comment) #:nodoc:
raise
NotImplementedError
,
"
#{
self
.
class
}
does not support changing column comments"
end
pr
otected
pr
ivate
def
add_index_sort_order
(
quoted_columns
,
**
options
)
def
add_index_sort_order
(
quoted_columns
,
**
options
)
# :doc:
if
order
=
options
[
:order
]
case
order
when
Hash
...
...
@@ -1186,7 +1186,7 @@ def add_index_sort_order(quoted_columns, **options)
end
# Overridden by the MySQL adapter for supporting index lengths
def
add_options_for_index_columns
(
quoted_columns
,
**
options
)
def
add_options_for_index_columns
(
quoted_columns
,
**
options
)
# :doc:
if
supports_index_sort_order?
quoted_columns
=
add_index_sort_order
(
quoted_columns
,
options
)
end
...
...
@@ -1194,14 +1194,14 @@ def add_options_for_index_columns(quoted_columns, **options)
quoted_columns
end
def
quoted_columns_for_index
(
column_names
,
**
options
)
def
quoted_columns_for_index
(
column_names
,
**
options
)
# :doc:
return
[
column_names
]
if
column_names
.
is_a?
(
String
)
quoted_columns
=
Hash
[
column_names
.
map
{
|
name
|
[
name
.
to_sym
,
quote_column_name
(
name
).
dup
]
}]
add_options_for_index_columns
(
quoted_columns
,
options
).
values
end
def
index_name_for_remove
(
table_name
,
options
=
{})
def
index_name_for_remove
(
table_name
,
options
=
{})
# :doc:
return
options
[
:name
]
if
can_remove_index_by_name?
(
options
)
checks
=
[]
...
...
@@ -1231,7 +1231,7 @@ def index_name_for_remove(table_name, options = {})
end
end
def
rename_table_indexes
(
table_name
,
new_name
)
def
rename_table_indexes
(
table_name
,
new_name
)
# :doc:
indexes
(
new_name
).
each
do
|
index
|
generated_index_name
=
index_name
(
table_name
,
column:
index
.
columns
)
if
generated_index_name
==
index
.
name
...
...
@@ -1240,7 +1240,7 @@ def rename_table_indexes(table_name, new_name)
end
end
def
rename_column_indexes
(
table_name
,
column_name
,
new_column_name
)
def
rename_column_indexes
(
table_name
,
column_name
,
new_column_name
)
# :doc:
column_name
,
new_column_name
=
column_name
.
to_s
,
new_column_name
.
to_s
indexes
(
table_name
).
each
do
|
index
|
next
unless
index
.
columns
.
include?
(
new_column_name
)
...
...
@@ -1253,7 +1253,6 @@ def rename_column_indexes(table_name, column_name, new_column_name)
end
end
private
def
create_table_definition
(
*
args
)
TableDefinition
.
new
(
*
args
)
end
...
...
activerecord/lib/active_record/connection_adapters/abstract_adapter.rb
浏览文件 @
5b14129d
...
...
@@ -499,9 +499,9 @@ def combine_bind_parameters(
result
end
pr
otected
pr
ivate
def
initialize_type_map
(
m
)
# :nodoc:
def
initialize_type_map
(
m
)
register_class_with_limit
m
,
%r(boolean)i
,
Type
::
Boolean
register_class_with_limit
m
,
%r(char)i
,
Type
::
String
register_class_with_limit
m
,
%r(binary)i
,
Type
::
Binary
...
...
@@ -532,37 +532,37 @@ def initialize_type_map(m) # :nodoc:
end
end
def
reload_type_map
# :nodoc:
def
reload_type_map
type_map
.
clear
initialize_type_map
(
type_map
)
end
def
register_class_with_limit
(
mapping
,
key
,
klass
)
# :nodoc:
def
register_class_with_limit
(
mapping
,
key
,
klass
)
mapping
.
register_type
(
key
)
do
|*
args
|
limit
=
extract_limit
(
args
.
last
)
klass
.
new
(
limit:
limit
)
end
end
def
register_class_with_precision
(
mapping
,
key
,
klass
)
# :nodoc:
def
register_class_with_precision
(
mapping
,
key
,
klass
)
mapping
.
register_type
(
key
)
do
|*
args
|
precision
=
extract_precision
(
args
.
last
)
klass
.
new
(
precision:
precision
)
end
end
def
extract_scale
(
sql_type
)
# :nodoc:
def
extract_scale
(
sql_type
)
case
sql_type
when
/\((\d+)\)/
then
0
when
/\((\d+)(,(\d+))\)/
then
$3
.
to_i
end
end
def
extract_precision
(
sql_type
)
# :nodoc:
def
extract_precision
(
sql_type
)
$1
.
to_i
if
sql_type
=~
/\((\d+)(,\d+)?\)/
end
def
extract_limit
(
sql_type
)
# :nodoc:
def
extract_limit
(
sql_type
)
case
sql_type
when
/^bigint/i
8
...
...
@@ -571,7 +571,7 @@ def extract_limit(sql_type) # :nodoc:
end
end
def
translate_exception_class
(
e
,
sql
)
def
translate_exception_class
(
e
,
sql
)
# :doc:
begin
message
=
"
#{
e
.
class
.
name
}
:
#{
e
.
message
}
:
#{
sql
}
"
rescue
Encoding
::
CompatibilityError
...
...
@@ -583,7 +583,7 @@ def translate_exception_class(e, sql)
exception
end
def
log
(
sql
,
name
=
"SQL"
,
binds
=
[],
type_casted_binds
=
[],
statement_name
=
nil
)
def
log
(
sql
,
name
=
"SQL"
,
binds
=
[],
type_casted_binds
=
[],
statement_name
=
nil
)
# :doc:
@instrumenter
.
instrument
(
"sql.active_record"
,
sql:
sql
,
...
...
@@ -596,7 +596,7 @@ def log(sql, name = "SQL", binds = [], type_casted_binds = [], statement_name =
raise
translate_exception_class
(
e
,
sql
)
end
def
translate_exception
(
exception
,
message
)
def
translate_exception
(
exception
,
message
)
# :doc:
# override in derived class
case
exception
when
RuntimeError
...
...
@@ -606,11 +606,11 @@ def translate_exception(exception, message)
end
end
def
without_prepared_statement?
(
binds
)
def
without_prepared_statement?
(
binds
)
# :doc:
!
prepared_statements
||
binds
.
empty?
end
def
column_for
(
table_name
,
column_name
)
# :nodoc:
def
column_for
(
table_name
,
column_name
)
column_name
=
column_name
.
to_s
columns
(
table_name
).
detect
{
|
c
|
c
.
name
==
column_name
}
||
raise
(
ActiveRecordError
,
"No such column:
#{
table_name
}
.
#{
column_name
}
"
)
...
...
activerecord/lib/active_record/connection_adapters/abstract_mysql_adapter.rb
浏览文件 @
5b14129d
...
...
@@ -649,9 +649,9 @@ def valid_type?(type)
!
native_database_types
[
type
].
nil?
end
pr
otected
pr
ivate
def
initialize_type_map
(
m
)
# :nodoc:
def
initialize_type_map
(
m
)
super
register_class_with_limit
m
,
%r(char)i
,
MysqlString
...
...
@@ -691,7 +691,7 @@ def initialize_type_map(m) # :nodoc:
end
end
def
register_integer_type
(
mapping
,
key
,
options
)
# :nodoc:
def
register_integer_type
(
mapping
,
key
,
options
)
mapping
.
register_type
(
key
)
do
|
sql_type
|
if
/\bunsigned\b/
.
match?
(
sql_type
)
Type
::
UnsignedInteger
.
new
(
options
)
...
...
@@ -701,7 +701,7 @@ def register_integer_type(mapping, key, options) # :nodoc:
end
end
def
extract_precision
(
sql_type
)
def
extract_precision
(
sql_type
)
# :doc:
if
/time/
.
match?
(
sql_type
)
super
||
0
else
...
...
@@ -709,11 +709,11 @@ def extract_precision(sql_type)
end
end
def
fetch_type_metadata
(
sql_type
,
extra
=
""
)
def
fetch_type_metadata
(
sql_type
,
extra
=
""
)
# :doc:
MySQL
::
TypeMetadata
.
new
(
super
(
sql_type
),
extra:
extra
)
end
def
add_index_length
(
quoted_columns
,
**
options
)
def
add_index_length
(
quoted_columns
,
**
options
)
# :doc:
if
length
=
options
[
:length
]
case
length
when
Hash
...
...
@@ -727,7 +727,7 @@ def add_index_length(quoted_columns, **options)
quoted_columns
end
def
add_options_for_index_columns
(
quoted_columns
,
**
options
)
def
add_options_for_index_columns
(
quoted_columns
,
**
options
)
# :doc:
quoted_columns
=
add_index_length
(
quoted_columns
,
options
)
super
end
...
...
@@ -743,7 +743,7 @@ def add_options_for_index_columns(quoted_columns, **options)
ER_CANNOT_ADD_FOREIGN
=
1215
ER_CANNOT_CREATE_TABLE
=
1005
def
translate_exception
(
exception
,
message
)
def
translate_exception
(
exception
,
message
)
# :doc:
case
error_number
(
exception
)
when
ER_DUP_ENTRY
RecordNotUnique
.
new
(
message
)
...
...
@@ -770,13 +770,13 @@ def translate_exception(exception, message)
end
end
def
add_column_sql
(
table_name
,
column_name
,
type
,
options
=
{})
def
add_column_sql
(
table_name
,
column_name
,
type
,
options
=
{})
# :doc:
td
=
create_table_definition
(
table_name
)
cd
=
td
.
new_column_definition
(
column_name
,
type
,
options
)
schema_creation
.
accept
(
AddColumnDefinition
.
new
(
cd
))
end
def
change_column_sql
(
table_name
,
column_name
,
type
,
options
=
{})
def
change_column_sql
(
table_name
,
column_name
,
type
,
options
=
{})
# :doc:
column
=
column_for
(
table_name
,
column_name
)
unless
options_include_default?
(
options
)
...
...
@@ -796,7 +796,7 @@ def change_column_sql(table_name, column_name, type, options = {})
schema_creation
.
accept
(
ChangeColumnDefinition
.
new
(
cd
,
column
.
name
))
end
def
rename_column_sql
(
table_name
,
column_name
,
new_column_name
)
def
rename_column_sql
(
table_name
,
column_name
,
new_column_name
)
# :doc:
column
=
column_for
(
table_name
,
column_name
)
options
=
{
default:
column
.
default
,
...
...
@@ -810,35 +810,33 @@ def rename_column_sql(table_name, column_name, new_column_name)
schema_creation
.
accept
(
ChangeColumnDefinition
.
new
(
cd
,
column
.
name
))
end
def
remove_column_sql
(
table_name
,
column_name
,
type
=
nil
,
options
=
{})
def
remove_column_sql
(
table_name
,
column_name
,
type
=
nil
,
options
=
{})
# :doc:
"DROP
#{
quote_column_name
(
column_name
)
}
"
end
def
remove_columns_sql
(
table_name
,
*
column_names
)
def
remove_columns_sql
(
table_name
,
*
column_names
)
# :doc:
column_names
.
map
{
|
column_name
|
remove_column_sql
(
table_name
,
column_name
)
}
end
def
add_index_sql
(
table_name
,
column_name
,
options
=
{})
def
add_index_sql
(
table_name
,
column_name
,
options
=
{})
# :doc:
index_name
,
index_type
,
index_columns
,
_
,
index_algorithm
,
index_using
=
add_index_options
(
table_name
,
column_name
,
options
)
index_algorithm
[
0
,
0
]
=
", "
if
index_algorithm
.
present?
"ADD
#{
index_type
}
INDEX
#{
quote_column_name
(
index_name
)
}
#{
index_using
}
(
#{
index_columns
}
)
#{
index_algorithm
}
"
end
def
remove_index_sql
(
table_name
,
options
=
{})
def
remove_index_sql
(
table_name
,
options
=
{})
# :doc:
index_name
=
index_name_for_remove
(
table_name
,
options
)
"DROP INDEX
#{
index_name
}
"
end
def
add_timestamps_sql
(
table_name
,
options
=
{})
def
add_timestamps_sql
(
table_name
,
options
=
{})
# :doc:
[
add_column_sql
(
table_name
,
:created_at
,
:datetime
,
options
),
add_column_sql
(
table_name
,
:updated_at
,
:datetime
,
options
)]
end
def
remove_timestamps_sql
(
table_name
,
options
=
{})
def
remove_timestamps_sql
(
table_name
,
options
=
{})
# :doc:
[
remove_column_sql
(
table_name
,
:updated_at
),
remove_column_sql
(
table_name
,
:created_at
)]
end
private
# MySQL is too stupid to create a temporary table for use subquery, so we have
# to give it some prompting in the form of a subsubquery. Ugh!
def
subquery_for
(
key
,
select
)
...
...
activerecord/lib/active_record/connection_adapters/mysql/database_statements.rb
浏览文件 @
5b14129d
...
...
@@ -52,14 +52,12 @@ def exec_delete(sql, name = nil, binds = [])
end
alias
:exec_update
:exec_delete
pr
otected
pr
ivate
def
last_inserted_id
(
result
)
def
last_inserted_id
(
result
)
# :doc:
@connection
.
last_id
end
private
def
select_result
(
sql
,
name
=
nil
,
binds
=
[])
if
without_prepared_statement?
(
binds
)
execute_and_free
(
sql
,
name
)
{
|
result
|
yield
result
}
...
...
activerecord/lib/active_record/connection_adapters/postgresql/utils.rb
浏览文件 @
5b14129d
...
...
@@ -34,7 +34,7 @@ def hash
parts
.
hash
end
pr
otected
pr
ivate
def
unquote
(
part
)
if
part
&&
part
.
start_with?
(
'"'
)
part
[
1
..-
2
]
...
...
activerecord/lib/active_record/connection_adapters/postgresql_adapter.rb
浏览文件 @
5b14129d
...
...
@@ -404,7 +404,7 @@ def postgresql_version
@connection
.
server_version
end
pr
otected
pr
ivate
# See http://www.postgresql.org/docs/current/static/errcodes-appendix.html
VALUE_LIMIT_VIOLATION
=
"22001"
...
...
@@ -415,7 +415,7 @@ def postgresql_version
SERIALIZATION_FAILURE
=
"40001"
DEADLOCK_DETECTED
=
"40P01"
def
translate_exception
(
exception
,
message
)
def
translate_exception
(
exception
,
message
)
# :doc:
return
exception
unless
exception
.
respond_to?
(
:result
)
case
exception
.
result
.
try
(
:error_field
,
PGresult
::
PG_DIAG_SQLSTATE
)
...
...
@@ -438,8 +438,6 @@ def translate_exception(exception, message)
end
end
private
def
get_oid_type
(
oid
,
fmod
,
column_name
,
sql_type
=
""
)
if
!
type_map
.
key?
(
oid
)
load_additional_types
(
type_map
,
[
oid
])
...
...
activerecord/lib/active_record/connection_adapters/sqlite3_adapter.rb
浏览文件 @
5b14129d
...
...
@@ -431,16 +431,16 @@ def rename_column(table_name, column_name, new_column_name) #:nodoc:
rename_column_indexes
(
table_name
,
column
.
name
,
new_column_name
)
end
pr
otected
pr
ivate
def
table_structure
(
table_name
)
# :nodoc:
def
table_structure
(
table_name
)
structure
=
exec_query
(
"PRAGMA table_info(
#{
quote_table_name
(
table_name
)
}
)"
,
"SCHEMA"
)
raise
(
ActiveRecord
::
StatementInvalid
,
"Could not find table '
#{
table_name
}
'"
)
if
structure
.
empty?
table_structure_with_collation
(
table_name
,
structure
)
end
alias
column_definitions
table_structure
def
alter_table
(
table_name
,
options
=
{})
#:nodoc:
def
alter_table
(
table_name
,
options
=
{})
altered_table_name
=
"a
#{
table_name
}
"
caller
=
lambda
{
|
definition
|
yield
definition
if
block_given?
}
...
...
@@ -451,12 +451,12 @@ def alter_table(table_name, options = {}) #:nodoc:
end
end
def
move_table
(
from
,
to
,
options
=
{},
&
block
)
#:nodoc:
def
move_table
(
from
,
to
,
options
=
{},
&
block
)
copy_table
(
from
,
to
,
options
,
&
block
)
drop_table
(
from
)
end
def
copy_table
(
from
,
to
,
options
=
{})
#:nodoc:
def
copy_table
(
from
,
to
,
options
=
{})
from_primary_key
=
primary_key
(
from
)
options
[
:id
]
=
false
create_table
(
to
,
options
)
do
|
definition
|
...
...
@@ -482,7 +482,7 @@ def copy_table(from, to, options = {}) #:nodoc:
options
[
:rename
]
||
{})
end
def
copy_table_indexes
(
from
,
to
,
rename
=
{})
#:nodoc:
def
copy_table_indexes
(
from
,
to
,
rename
=
{})
indexes
(
from
).
each
do
|
index
|
name
=
index
.
name
if
to
==
"a
#{
from
}
"
...
...
@@ -505,7 +505,7 @@ def copy_table_indexes(from, to, rename = {}) #:nodoc:
end
end
def
copy_table_contents
(
from
,
to
,
columns
,
rename
=
{})
#:nodoc:
def
copy_table_contents
(
from
,
to
,
columns
,
rename
=
{})
column_mappings
=
Hash
[
columns
.
map
{
|
name
|
[
name
,
name
]
}]
rename
.
each
{
|
a
|
column_mappings
[
a
.
last
]
=
a
.
first
}
from_columns
=
columns
(
from
).
collect
(
&
:name
)
...
...
@@ -518,11 +518,11 @@ def copy_table_contents(from, to, columns, rename = {}) #:nodoc:
SELECT
#{
quoted_from_columns
}
FROM
#{
quote_table_name
(
from
)
}
"
)
end
def
sqlite_version
def
sqlite_version
# :doc:
@sqlite_version
||=
SQLite3Adapter
::
Version
.
new
(
select_value
(
"select sqlite_version(*)"
))
end
def
translate_exception
(
exception
,
message
)
def
translate_exception
(
exception
,
message
)
# :doc:
case
exception
.
message
# SQLite 3.8.2 returns a newly formatted error message:
# UNIQUE constraint failed: *table_name*.*column_name*
...
...
@@ -537,7 +537,6 @@ def translate_exception(exception, message)
end
end
private
COLLATE_REGEX
=
/.*\"(\w+)\".*collate\s+\"(\w+)\".*/i
.
freeze
def
table_structure_with_collation
(
table_name
,
basic_structure
)
...
...
activerecord/lib/active_record/railties/controller_runtime.rb
浏览文件 @
5b14129d
...
...
@@ -12,6 +12,8 @@ module ControllerRuntime #:nodoc:
attr_internal
:db_runtime
private
def
process_action
(
action
,
*
args
)
# We also need to reset the runtime before each action
# because of queries in middleware or in cases we are streaming
...
...
activerecord/lib/active_record/relation/delegation.rb
浏览文件 @
5b14129d
...
...
@@ -78,7 +78,7 @@ def delegate(method, opts = {})
end
end
pr
otected
pr
ivate
def
method_missing
(
method
,
*
args
,
&
block
)
if
@klass
.
respond_to?
(
method
)
...
...
activerecord/lib/active_record/relation/finder_methods.rb
浏览文件 @
5b14129d
...
...
@@ -439,9 +439,9 @@ def using_limitable_reflections?(reflections)
reflections
.
none?
(
&
:collection?
)
end
protected
private
def
find_with_ids
(
*
ids
)
def
find_with_ids
(
*
ids
)
# :doc:
raise
UnknownPrimaryKey
.
new
(
@klass
)
if
primary_key
.
nil?
expects_array
=
ids
.
first
.
kind_of?
(
Array
)
...
...
@@ -462,7 +462,7 @@ def find_with_ids(*ids)
raise
RecordNotFound
,
"Couldn't find
#{
@klass
.
name
}
with an out of range ID"
end
def
find_one
(
id
)
def
find_one
(
id
)
# :doc:
if
ActiveRecord
::
Base
===
id
id
=
id
.
id
ActiveSupport
::
Deprecation
.
warn
(
<<-
MSG
.
squish
)
...
...
@@ -479,7 +479,7 @@ def find_one(id)
record
end
def
find_some
(
ids
)
def
find_some
(
ids
)
# :doc:
return
find_some_ordered
(
ids
)
unless
order_values
.
present?
result
=
where
(
primary_key
=>
ids
).
to_a
...
...
@@ -503,7 +503,7 @@ def find_some(ids)
end
end
def
find_some_ordered
(
ids
)
def
find_some_ordered
(
ids
)
# :doc:
ids
=
ids
.
slice
(
offset_value
||
0
,
limit_value
||
ids
.
size
)
||
[]
result
=
except
(
:limit
,
:offset
).
where
(
primary_key
=>
ids
).
records
...
...
@@ -518,7 +518,7 @@ def find_some_ordered(ids)
end
end
def
find_take
def
find_take
# :doc:
if
loaded?
records
.
first
else
...
...
@@ -526,7 +526,7 @@ def find_take
end
end
def
find_take_with_limit
(
limit
)
def
find_take_with_limit
(
limit
)
# :doc:
if
loaded?
records
.
take
(
limit
)
else
...
...
@@ -534,11 +534,11 @@ def find_take_with_limit(limit)
end
end
def
find_nth
(
index
)
def
find_nth
(
index
)
# :doc:
@offsets
[
offset_index
+
index
]
||=
find_nth_with_limit
(
index
,
1
).
first
end
def
find_nth_with_limit
(
index
,
limit
)
def
find_nth_with_limit
(
index
,
limit
)
# :doc:
if
loaded?
records
[
index
,
limit
]
||
[]
else
...
...
@@ -553,7 +553,7 @@ def find_nth_with_limit(index, limit)
end
end
def
find_nth_from_last
(
index
)
def
find_nth_from_last
(
index
)
# :doc:
if
loaded?
records
[
-
index
]
else
...
...
@@ -572,8 +572,6 @@ def find_nth_from_last(index)
end
end
private
def
find_last
(
limit
)
limit
?
records
.
last
(
limit
)
:
records
.
last
end
...
...
activerecord/lib/active_record/sanitization.rb
浏览文件 @
5b14129d
...
...
@@ -4,7 +4,7 @@ module Sanitization
extend
ActiveSupport
::
Concern
module
ClassMethods
pr
otected
pr
ivate
# Accepts an array or string of SQL conditions and sanitizes
# them into a valid SQL fragment for a WHERE clause.
...
...
@@ -20,7 +20,7 @@ module ClassMethods
#
# sanitize_sql_for_conditions("name='foo''bar' and group_id='4'")
# # => "name='foo''bar' and group_id='4'"
def
sanitize_sql_for_conditions
(
condition
)
def
sanitize_sql_for_conditions
(
condition
)
# :doc:
return
nil
if
condition
.
blank?
case
condition
...
...
@@ -46,7 +46,7 @@ def sanitize_sql_for_conditions(condition)
#
# sanitize_sql_for_assignment("name=NULL and group_id='4'")
# # => "name=NULL and group_id='4'"
def
sanitize_sql_for_assignment
(
assignments
,
default_table_name
=
self
.
table_name
)
def
sanitize_sql_for_assignment
(
assignments
,
default_table_name
=
self
.
table_name
)
# :doc:
case
assignments
when
Array
;
sanitize_sql_array
(
assignments
)
when
Hash
;
sanitize_sql_hash_for_assignment
(
assignments
,
default_table_name
)
...
...
@@ -62,7 +62,7 @@ def sanitize_sql_for_assignment(assignments, default_table_name = self.table_nam
#
# sanitize_sql_for_order("id ASC")
# # => "id ASC"
def
sanitize_sql_for_order
(
condition
)
def
sanitize_sql_for_order
(
condition
)
# :doc:
if
condition
.
is_a?
(
Array
)
&&
condition
.
first
.
to_s
.
include?
(
"?"
)
sanitize_sql_array
(
condition
)
else
...
...
@@ -85,7 +85,7 @@ def sanitize_sql_for_order(condition)
#
# { address: Address.new("813 abc st.", "chicago") }
# # => { address_street: "813 abc st.", address_city: "chicago" }
def
expand_hash_conditions_for_aggregates
(
attrs
)
def
expand_hash_conditions_for_aggregates
(
attrs
)
# :doc:
expanded_attrs
=
{}
attrs
.
each
do
|
attr
,
value
|
if
aggregation
=
reflect_on_aggregation
(
attr
.
to_sym
)
...
...
@@ -108,7 +108,7 @@ def expand_hash_conditions_for_aggregates(attrs)
#
# sanitize_sql_hash_for_assignment({ status: nil, group_id: 1 }, "posts")
# # => "`posts`.`status` = NULL, `posts`.`group_id` = 1"
def
sanitize_sql_hash_for_assignment
(
attrs
,
table
)
def
sanitize_sql_hash_for_assignment
(
attrs
,
table
)
# :doc:
c
=
connection
attrs
.
map
do
|
attr
,
value
|
value
=
type_for_attribute
(
attr
.
to_s
).
serialize
(
value
)
...
...
@@ -130,7 +130,7 @@ def sanitize_sql_hash_for_assignment(attrs, table)
#
# sanitize_sql_like("snake_cased_string", "!")
# # => "snake!_cased!_string"
def
sanitize_sql_like
(
string
,
escape_character
=
"
\\
"
)
def
sanitize_sql_like
(
string
,
escape_character
=
"
\\
"
)
# :doc:
pattern
=
Regexp
.
union
(
escape_character
,
"%"
,
"_"
)
string
.
gsub
(
pattern
)
{
|
x
|
[
escape_character
,
x
].
join
}
end
...
...
@@ -146,7 +146,7 @@ def sanitize_sql_like(string, escape_character = "\\")
#
# sanitize_sql_array(["name='%s' and group_id='%s'", "foo'bar", 4])
# # => "name='foo''bar' and group_id='4'"
def
sanitize_sql_array
(
ary
)
def
sanitize_sql_array
(
ary
)
# :doc:
statement
,
*
values
=
ary
if
values
.
first
.
is_a?
(
Hash
)
&&
/:\w+/
.
match?
(
statement
)
replace_named_bind_variables
(
statement
,
values
.
first
)
...
...
@@ -159,7 +159,7 @@ def sanitize_sql_array(ary)
end
end
def
replace_bind_variables
(
statement
,
values
)
# :nodoc:
def
replace_bind_variables
(
statement
,
values
)
raise_if_bind_arity_mismatch
(
statement
,
statement
.
count
(
"?"
),
values
.
size
)
bound
=
values
.
dup
c
=
connection
...
...
@@ -168,7 +168,7 @@ def replace_bind_variables(statement, values) # :nodoc:
end
end
def
replace_bind_variable
(
value
,
c
=
connection
)
# :nodoc:
def
replace_bind_variable
(
value
,
c
=
connection
)
if
ActiveRecord
::
Relation
===
value
value
.
to_sql
else
...
...
@@ -176,7 +176,7 @@ def replace_bind_variable(value, c = connection) # :nodoc:
end
end
def
replace_named_bind_variables
(
statement
,
bind_vars
)
# :nodoc:
def
replace_named_bind_variables
(
statement
,
bind_vars
)
statement
.
gsub
(
/(:?):([a-zA-Z]\w*)/
)
do
|
match
|
if
$1
==
":"
# skip postgresql casts
match
# return the whole match
...
...
@@ -188,7 +188,7 @@ def replace_named_bind_variables(statement, bind_vars) # :nodoc:
end
end
def
quote_bound_value
(
value
,
c
=
connection
)
# :nodoc:
def
quote_bound_value
(
value
,
c
=
connection
)
if
value
.
respond_to?
(
:map
)
&&
!
value
.
acts_like?
(
:string
)
if
value
.
respond_to?
(
:empty?
)
&&
value
.
empty?
c
.
quote
(
nil
)
...
...
@@ -200,7 +200,7 @@ def quote_bound_value(value, c = connection) # :nodoc:
end
end
def
raise_if_bind_arity_mismatch
(
statement
,
expected
,
provided
)
# :nodoc:
def
raise_if_bind_arity_mismatch
(
statement
,
expected
,
provided
)
unless
expected
==
provided
raise
PreparedStatementInvalid
,
"wrong number of bind variables (
#{
provided
}
for
#{
expected
}
) in:
#{
statement
}
"
end
...
...
activerecord/lib/active_record/scoping/default.rb
浏览文件 @
5b14129d
...
...
@@ -44,7 +44,7 @@ def before_remove_const #:nodoc:
self
.
current_scope
=
nil
end
pr
otected
pr
ivate
# Use this macro in your model to set a default scope for all operations on
# the model.
...
...
@@ -87,7 +87,7 @@ def before_remove_const #:nodoc:
# # Should return a scope, you can call 'super' here etc.
# end
# end
def
default_scope
(
scope
=
nil
)
def
default_scope
(
scope
=
nil
)
# :doc:
scope
=
Proc
.
new
if
block_given?
if
scope
.
is_a?
(
Relation
)
||
!
scope
.
respond_to?
(
:call
)
...
...
@@ -101,7 +101,7 @@ def default_scope(scope = nil)
self
.
default_scopes
+=
[
scope
]
end
def
build_default_scope
(
base_rel
=
nil
)
# :nodoc:
def
build_default_scope
(
base_rel
=
nil
)
return
if
abstract_class?
if
default_scope_override
.
nil?
...
...
@@ -122,18 +122,18 @@ def build_default_scope(base_rel = nil) # :nodoc:
end
end
def
ignore_default_scope?
# :nodoc:
def
ignore_default_scope?
ScopeRegistry
.
value_for
(
:ignore_default_scope
,
base_class
)
end
def
ignore_default_scope
=
(
ignore
)
# :nodoc:
def
ignore_default_scope
=
(
ignore
)
ScopeRegistry
.
set_value_for
(
:ignore_default_scope
,
base_class
,
ignore
)
end
# The ignore_default_scope flag is used to prevent an infinite recursion
# situation where a default scope references a scope which has a default
# scope which references a scope...
def
evaluate_default_scope
# :nodoc:
def
evaluate_default_scope
return
if
ignore_default_scope?
begin
...
...
activerecord/lib/active_record/scoping/named.rb
浏览文件 @
5b14129d
...
...
@@ -171,9 +171,9 @@ def scope(name, body, &block)
end
end
pr
otected
pr
ivate
def
valid_scope_name?
(
name
)
def
valid_scope_name?
(
name
)
# :doc:
if
respond_to?
(
name
,
true
)
&&
logger
logger
.
warn
"Creating scope :
#{
name
}
. "
\
"Overwriting existing method
#{
self
.
name
}
.
#{
name
}
."
...
...
activerecord/lib/active_record/store.rb
浏览文件 @
5b14129d
...
...
@@ -121,18 +121,17 @@ def stored_attributes
end
end
pr
otected
def
read_store_attribute
(
store_attribute
,
key
)
pr
ivate
def
read_store_attribute
(
store_attribute
,
key
)
# :doc:
accessor
=
store_accessor_for
(
store_attribute
)
accessor
.
read
(
self
,
store_attribute
,
key
)
end
def
write_store_attribute
(
store_attribute
,
key
,
value
)
def
write_store_attribute
(
store_attribute
,
key
,
value
)
# :doc:
accessor
=
store_accessor_for
(
store_attribute
)
accessor
.
write
(
self
,
store_attribute
,
key
,
value
)
end
private
def
store_accessor_for
(
store_attribute
)
type_for_attribute
(
store_attribute
.
to_s
).
accessor
end
...
...
activerecord/lib/active_record/transactions.rb
浏览文件 @
5b14129d
...
...
@@ -407,10 +407,10 @@ def with_transaction_returning_status
end
end
pr
otected
pr
ivate
# Save the new record state and id of a record so it can be restored later if a transaction fails.
def
remember_transaction_record_state
#:nodoc:
def
remember_transaction_record_state
@_start_transaction_state
[
:id
]
=
id
@_start_transaction_state
.
reverse_merge!
(
new_record:
@new_record
,
...
...
@@ -421,18 +421,18 @@ def remember_transaction_record_state #:nodoc:
end
# Clear the new record state and id of a record.
def
clear_transaction_record_state
#:nodoc:
def
clear_transaction_record_state
@_start_transaction_state
[
:level
]
=
(
@_start_transaction_state
[
:level
]
||
0
)
-
1
force_clear_transaction_record_state
if
@_start_transaction_state
[
:level
]
<
1
end
# Force to clear the transaction record state.
def
force_clear_transaction_record_state
#:nodoc:
def
force_clear_transaction_record_state
@_start_transaction_state
.
clear
end
# Restore the new record state and id of a record that was previously saved by a call to save_record_state.
def
restore_transaction_record_state
(
force
=
false
)
#:nodoc:
def
restore_transaction_record_state
(
force
=
false
)
unless
@_start_transaction_state
.
empty?
transaction_level
=
(
@_start_transaction_state
[
:level
]
||
0
)
-
1
if
transaction_level
<
1
||
force
...
...
@@ -450,12 +450,12 @@ def restore_transaction_record_state(force = false) #:nodoc:
end
# Determine if a record was created or destroyed in a transaction. State should be one of :new_record or :destroyed.
def
transaction_record_state
(
state
)
#:nodoc:
def
transaction_record_state
(
state
)
@_start_transaction_state
[
state
]
end
# Determine if a transaction included an action for :create, :update, or :destroy. Used in filtering callbacks.
def
transaction_include_any_action?
(
actions
)
#:nodoc:
def
transaction_include_any_action?
(
actions
)
actions
.
any?
do
|
action
|
case
action
when
:create
...
...
@@ -469,8 +469,6 @@ def transaction_include_any_action?(actions) #:nodoc:
end
end
private
def
set_transaction_state
(
state
)
@transaction_state
=
state
end
...
...
activerecord/lib/active_record/validations.rb
浏览文件 @
5b14129d
...
...
@@ -68,17 +68,17 @@ def valid?(context = nil)
alias_method
:validate
,
:valid?
pr
otected
pr
ivate
def
default_validation_context
def
default_validation_context
# :doc:
new_record?
?
:create
:
:update
end
def
raise_validation_error
def
raise_validation_error
# :doc:
raise
(
RecordInvalid
.
new
(
self
))
end
def
perform_validations
(
options
=
{})
# :nodoc:
def
perform_validations
(
options
=
{})
options
[
:validate
]
==
false
||
valid?
(
options
[
:context
])
end
end
...
...
activerecord/lib/active_record/validations/uniqueness.rb
浏览文件 @
5b14129d
...
...
@@ -33,13 +33,13 @@ def validate_each(record, attribute, value)
end
end
pr
otected
pr
ivate
# The check for an existing value should be run from a class that
# isn't abstract. This means working down from the current class
# (self), to the first non-abstract class. Since classes don't know
# their subclasses, we have to build the hierarchy between self and
# the record's class.
def
find_finder_class_for
(
record
)
#:nodoc:
def
find_finder_class_for
(
record
)
class_hierarchy
=
[
record
.
class
]
while
class_hierarchy
.
first
!=
@klass
...
...
@@ -49,7 +49,7 @@ def find_finder_class_for(record) #:nodoc:
class_hierarchy
.
detect
{
|
klass
|
!
klass
.
abstract_class?
}
end
def
build_relation
(
klass
,
attribute
,
value
)
# :nodoc:
def
build_relation
(
klass
,
attribute
,
value
)
if
reflection
=
klass
.
_reflect_on_association
(
attribute
)
attribute
=
reflection
.
foreign_key
value
=
value
.
attributes
[
reflection
.
klass
.
primary_key
]
unless
value
.
nil?
...
...
@@ -83,7 +83,7 @@ def build_relation(klass, attribute, value) # :nodoc:
end
end
def
scope_relation
(
record
,
relation
)
def
scope_relation
(
record
,
relation
)
# :doc:
Array
(
options
[
:scope
]).
each
do
|
scope_item
|
scope_value
=
if
record
.
class
.
_reflect_on_association
(
scope_item
)
record
.
association
(
scope_item
).
reader
...
...
@@ -96,7 +96,7 @@ def scope_relation(record, relation)
relation
end
def
map_enum_attribute
(
klass
,
attribute
,
value
)
def
map_enum_attribute
(
klass
,
attribute
,
value
)
# :doc:
mapping
=
klass
.
defined_enums
[
attribute
.
to_s
]
value
=
mapping
[
value
]
if
value
&&
mapping
value
...
...
activerecord/lib/rails/generators/active_record/migration/migration_generator.rb
浏览文件 @
5b14129d
...
...
@@ -18,10 +18,12 @@ def create_migration_file
protected
attr_reader
:migration_action
,
:join_tables
private
# Sets the default migration template that is being used for the generation of the migration.
# Depending on command line arguments, the migration template and the table name instance
# variables are set up.
def
set_local_assigns!
def
set_local_assigns!
# :doc:
@migration_template
=
"migration.rb"
case
file_name
when
/^(add|remove)_.*_(?:to|from)_(.*)/
...
...
@@ -40,13 +42,13 @@ def set_local_assigns!
end
end
def
set_index_names
def
set_index_names
# :doc:
attributes
.
each_with_index
do
|
attr
,
i
|
attr
.
index_name
=
[
attr
,
attributes
[
i
-
1
]].
map
{
|
a
|
index_name_for
(
a
)
}
end
end
def
index_name_for
(
attribute
)
def
index_name_for
(
attribute
)
# :doc:
if
attribute
.
foreign_key?
attribute
.
name
else
...
...
@@ -54,7 +56,6 @@ def index_name_for(attribute)
end
.
to_sym
end
private
def
attributes_with_index
attributes
.
select
{
|
a
|
!
a
.
reference?
&&
a
.
has_index?
}
end
...
...
activerecord/lib/rails/generators/active_record/model/model_generator.rb
浏览文件 @
5b14129d
...
...
@@ -33,31 +33,31 @@ def create_module_file
hook_for
:test_framework
pr
otected
pr
ivate
def
attributes_with_index
def
attributes_with_index
# :doc:
attributes
.
select
{
|
a
|
!
a
.
reference?
&&
a
.
has_index?
}
end
# FIXME: Change this file to a symlink once RubyGems 2.5.0 is required.
def
generate_application_record
def
generate_application_record
# :doc:
if
self
.
behavior
==
:invoke
&&
!
application_record_exist?
template
"application_record.rb"
,
application_record_file_name
end
end
# Used by the migration template to determine the parent name of the model
def
parent_class_name
def
parent_class_name
# :doc:
options
[
:parent
]
||
"ApplicationRecord"
end
def
application_record_exist?
def
application_record_exist?
# :doc:
file_exist
=
nil
in_root
{
file_exist
=
File
.
exist?
(
application_record_file_name
)
}
file_exist
end
def
application_record_file_name
def
application_record_file_name
# :doc:
@application_record_file_name
||=
if
mountable_engine?
"app/models/
#{
namespaced_path
}
/application_record.rb"
else
...
...
编辑
预览
Markdown
is supported
0%
请重试
或
添加新附件
.
添加附件
取消
You are about to add
0
people
to the discussion. Proceed with caution.
先完成此消息的编辑!
取消
想要评论请
注册
或
登录