composite_primary_keys 14.0.7 → 14.0.8
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/History.rdoc +7 -0
- data/README.rdoc +182 -182
- data/lib/composite_primary_keys/associations/collection_association.rb +38 -38
- data/lib/composite_primary_keys/associations/preloader/association.rb +52 -52
- data/lib/composite_primary_keys/autosave_association.rb +60 -60
- data/lib/composite_primary_keys/composite_arrays.rb +88 -88
- data/lib/composite_primary_keys/composite_predicates.rb +121 -121
- data/lib/composite_primary_keys/persistence.rb +96 -96
- data/lib/composite_primary_keys/relation/calculations.rb +110 -110
- data/lib/composite_primary_keys/validations/uniqueness.rb +40 -40
- data/lib/composite_primary_keys/version.rb +1 -1
- data/test/fixtures/department.rb +20 -20
- data/test/fixtures/room_assignment.rb +18 -18
- data/test/test_composite_arrays.rb +44 -44
- metadata +3 -3
@@ -1,96 +1,96 @@
|
|
1
|
-
module ActiveRecord
|
2
|
-
module Persistence
|
3
|
-
module ClassMethods
|
4
|
-
def delete(id_or_array)
|
5
|
-
# CPK
|
6
|
-
if self.composite?
|
7
|
-
id_or_array = if id_or_array.is_a?(CompositePrimaryKeys::CompositeKeys)
|
8
|
-
[id_or_array]
|
9
|
-
else
|
10
|
-
Array(id_or_array)
|
11
|
-
end
|
12
|
-
|
13
|
-
# Delete should return the number of deleted records
|
14
|
-
id_or_array.map do |id|
|
15
|
-
# Is the passed in id actually a record?
|
16
|
-
id = id.kind_of?(::ActiveRecord::Base) ? id.id : id
|
17
|
-
delete_by(cpk_id_predicate(self.arel_table, self.primary_key, id))
|
18
|
-
end.sum
|
19
|
-
else
|
20
|
-
delete_by(primary_key => id_or_array)
|
21
|
-
end
|
22
|
-
end
|
23
|
-
|
24
|
-
def _update_record(values, constraints) # :nodoc:
|
25
|
-
# CPK
|
26
|
-
if self.composite? && constraints[primary_key]
|
27
|
-
primary_key_values = constraints.delete(primary_key)
|
28
|
-
primary_key.each_with_index do |key, i|
|
29
|
-
constraints[key] = primary_key_values[i]
|
30
|
-
end
|
31
|
-
end
|
32
|
-
|
33
|
-
constraints = constraints.map { |name, value| predicate_builder[name, value] }
|
34
|
-
|
35
|
-
default_constraint = build_default_constraint
|
36
|
-
constraints << default_constraint if default_constraint
|
37
|
-
|
38
|
-
if current_scope = self.global_current_scope
|
39
|
-
constraints << current_scope.where_clause.ast
|
40
|
-
end
|
41
|
-
|
42
|
-
um = Arel::UpdateManager.new(arel_table)
|
43
|
-
um.set(values.transform_keys { |name| arel_table[name] })
|
44
|
-
um.wheres = constraints
|
45
|
-
|
46
|
-
connection.update(um, "#{self} Update")
|
47
|
-
end
|
48
|
-
|
49
|
-
def _delete_record(constraints) # :nodoc:
|
50
|
-
# CPK
|
51
|
-
if self.composite? && constraints[primary_key]
|
52
|
-
primary_key_values = constraints.delete(primary_key)
|
53
|
-
primary_key.each_with_index do |key, i|
|
54
|
-
constraints[key] = primary_key_values[i]
|
55
|
-
end
|
56
|
-
end
|
57
|
-
|
58
|
-
constraints = constraints.map { |name, value| predicate_builder[name, value] }
|
59
|
-
|
60
|
-
default_constraint = build_default_constraint
|
61
|
-
constraints << default_constraint if default_constraint
|
62
|
-
|
63
|
-
if current_scope = self.global_current_scope
|
64
|
-
constraints << current_scope.where_clause.ast
|
65
|
-
end
|
66
|
-
|
67
|
-
dm = Arel::DeleteManager.new(arel_table)
|
68
|
-
dm.wheres = constraints
|
69
|
-
|
70
|
-
connection.delete(dm, "#{self} Destroy")
|
71
|
-
end
|
72
|
-
end
|
73
|
-
|
74
|
-
def _create_record(attribute_names = self.attribute_names)
|
75
|
-
attribute_names = attributes_for_create(attribute_names)
|
76
|
-
|
77
|
-
new_id = self.class._insert_record(
|
78
|
-
attributes_with_values(attribute_names)
|
79
|
-
)
|
80
|
-
|
81
|
-
# CPK
|
82
|
-
if self.composite?
|
83
|
-
self.id = self.id.zip(Array(new_id)).map {|id1, id2| id2.nil? ? id1 : id2}
|
84
|
-
else
|
85
|
-
self.id ||= new_id if self.class.primary_key
|
86
|
-
end
|
87
|
-
|
88
|
-
@new_record = false
|
89
|
-
@previously_new_record = true
|
90
|
-
|
91
|
-
yield(self) if block_given?
|
92
|
-
|
93
|
-
id
|
94
|
-
end
|
95
|
-
end
|
96
|
-
end
|
1
|
+
module ActiveRecord
|
2
|
+
module Persistence
|
3
|
+
module ClassMethods
|
4
|
+
def delete(id_or_array)
|
5
|
+
# CPK
|
6
|
+
if self.composite?
|
7
|
+
id_or_array = if id_or_array.is_a?(CompositePrimaryKeys::CompositeKeys)
|
8
|
+
[id_or_array]
|
9
|
+
else
|
10
|
+
Array(id_or_array)
|
11
|
+
end
|
12
|
+
|
13
|
+
# Delete should return the number of deleted records
|
14
|
+
id_or_array.map do |id|
|
15
|
+
# Is the passed in id actually a record?
|
16
|
+
id = id.kind_of?(::ActiveRecord::Base) ? id.id : id
|
17
|
+
delete_by(cpk_id_predicate(self.arel_table, self.primary_key, id))
|
18
|
+
end.sum
|
19
|
+
else
|
20
|
+
delete_by(primary_key => id_or_array)
|
21
|
+
end
|
22
|
+
end
|
23
|
+
|
24
|
+
def _update_record(values, constraints) # :nodoc:
|
25
|
+
# CPK
|
26
|
+
if self.composite? && constraints[primary_key]
|
27
|
+
primary_key_values = constraints.delete(primary_key)
|
28
|
+
primary_key.each_with_index do |key, i|
|
29
|
+
constraints[key] = primary_key_values[i]
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
constraints = constraints.map { |name, value| predicate_builder[name, value] }
|
34
|
+
|
35
|
+
default_constraint = build_default_constraint
|
36
|
+
constraints << default_constraint if default_constraint
|
37
|
+
|
38
|
+
if current_scope = self.global_current_scope
|
39
|
+
constraints << current_scope.where_clause.ast
|
40
|
+
end
|
41
|
+
|
42
|
+
um = Arel::UpdateManager.new(arel_table)
|
43
|
+
um.set(values.transform_keys { |name| arel_table[name] })
|
44
|
+
um.wheres = constraints
|
45
|
+
|
46
|
+
connection.update(um, "#{self} Update")
|
47
|
+
end
|
48
|
+
|
49
|
+
def _delete_record(constraints) # :nodoc:
|
50
|
+
# CPK
|
51
|
+
if self.composite? && constraints[primary_key]
|
52
|
+
primary_key_values = constraints.delete(primary_key)
|
53
|
+
primary_key.each_with_index do |key, i|
|
54
|
+
constraints[key] = primary_key_values[i]
|
55
|
+
end
|
56
|
+
end
|
57
|
+
|
58
|
+
constraints = constraints.map { |name, value| predicate_builder[name, value] }
|
59
|
+
|
60
|
+
default_constraint = build_default_constraint
|
61
|
+
constraints << default_constraint if default_constraint
|
62
|
+
|
63
|
+
if current_scope = self.global_current_scope
|
64
|
+
constraints << current_scope.where_clause.ast
|
65
|
+
end
|
66
|
+
|
67
|
+
dm = Arel::DeleteManager.new(arel_table)
|
68
|
+
dm.wheres = constraints
|
69
|
+
|
70
|
+
connection.delete(dm, "#{self} Destroy")
|
71
|
+
end
|
72
|
+
end
|
73
|
+
|
74
|
+
def _create_record(attribute_names = self.attribute_names)
|
75
|
+
attribute_names = attributes_for_create(attribute_names)
|
76
|
+
|
77
|
+
new_id = self.class._insert_record(
|
78
|
+
attributes_with_values(attribute_names)
|
79
|
+
)
|
80
|
+
|
81
|
+
# CPK
|
82
|
+
if self.composite?
|
83
|
+
self.id = self.id.zip(Array(new_id)).map {|id1, id2| id2.nil? ? id1 : id2}
|
84
|
+
else
|
85
|
+
self.id ||= new_id if self.class.primary_key
|
86
|
+
end
|
87
|
+
|
88
|
+
@new_record = false
|
89
|
+
@previously_new_record = true
|
90
|
+
|
91
|
+
yield(self) if block_given?
|
92
|
+
|
93
|
+
id
|
94
|
+
end
|
95
|
+
end
|
96
|
+
end
|
@@ -1,110 +1,110 @@
|
|
1
|
-
module CompositePrimaryKeys
|
2
|
-
module ActiveRecord
|
3
|
-
module Calculations
|
4
|
-
def aggregate_column(column_name)
|
5
|
-
# CPK
|
6
|
-
if column_name.kind_of?(Array)
|
7
|
-
# Note: Test don't seem to run this code?
|
8
|
-
column_name.map do |column|
|
9
|
-
@klass.arel_table[column]
|
10
|
-
end
|
11
|
-
elsif @klass.has_attribute?(column_name) || @klass.attribute_alias?(column_name)
|
12
|
-
@klass.arel_table[column_name]
|
13
|
-
else
|
14
|
-
Arel.sql(column_name == :all ? "*" : column_name.to_s)
|
15
|
-
end
|
16
|
-
end
|
17
|
-
|
18
|
-
def execute_simple_calculation(operation, column_name, distinct) #:nodoc:
|
19
|
-
column_alias = column_name
|
20
|
-
|
21
|
-
# CPK
|
22
|
-
# if operation == "count" && (column_name == :all && distinct || has_limit_or_offset?)
|
23
|
-
# # Shortcut when limit is zero.
|
24
|
-
# return 0 if limit_value == 0
|
25
|
-
#
|
26
|
-
# query_builder = build_count_subquery(spawn, column_name, distinct)
|
27
|
-
if operation == "count"
|
28
|
-
relation = unscope(:order)
|
29
|
-
query_builder = build_count_subquery(spawn, column_name, distinct)
|
30
|
-
else
|
31
|
-
# PostgreSQL doesn't like ORDER BY when there are no GROUP BY
|
32
|
-
relation = unscope(:order).distinct!(false)
|
33
|
-
|
34
|
-
column = aggregate_column(column_name)
|
35
|
-
select_value = operation_over_aggregate_column(column, operation, distinct)
|
36
|
-
select_value.distinct = true if operation == "sum" && distinct
|
37
|
-
|
38
|
-
relation.select_values = [select_value]
|
39
|
-
|
40
|
-
query_builder = relation.arel
|
41
|
-
end
|
42
|
-
|
43
|
-
result = skip_query_cache_if_necessary { @klass.connection.select_all(query_builder) }
|
44
|
-
|
45
|
-
if operation != "count"
|
46
|
-
type = column.try(:type_caster) ||
|
47
|
-
lookup_cast_type_from_join_dependencies(column_name.to_s) || ::ActiveRecord::Type.default_value
|
48
|
-
type = type.subtype if ::ActiveRecord::Enum::EnumType === type
|
49
|
-
end
|
50
|
-
|
51
|
-
type_cast_calculated_value(result.cast_values.first, operation, type) do |value|
|
52
|
-
type = column.try(:type_caster) ||
|
53
|
-
# CPK
|
54
|
-
# lookup_cast_type_from_join_dependencies(column_name.to_s) || Type.default_value
|
55
|
-
lookup_cast_type_from_join_dependencies(column_name.to_s) || ::ActiveRecord::Type.default_value
|
56
|
-
type.deserialize(value)
|
57
|
-
end
|
58
|
-
end
|
59
|
-
|
60
|
-
def build_count_subquery(relation, column_name, distinct)
|
61
|
-
if column_name == :all
|
62
|
-
column_alias = Arel.star
|
63
|
-
# CPK
|
64
|
-
# relation.select_values = [ Arel.sql(FinderMethods::ONE_AS_ONE) ] unless distinct
|
65
|
-
relation.select_values = [ Arel.sql(::ActiveRecord::FinderMethods::ONE_AS_ONE) ] unless distinct
|
66
|
-
elsif column_name.is_a?(Array)
|
67
|
-
column_alias = Arel.star
|
68
|
-
relation.select_values = column_name.map do |column|
|
69
|
-
Arel::Attribute.new(@klass.unscoped.table, column)
|
70
|
-
end
|
71
|
-
else
|
72
|
-
column_alias = Arel.sql("count_column")
|
73
|
-
relation.select_values = [ aggregate_column(column_name).as(column_alias) ]
|
74
|
-
end
|
75
|
-
|
76
|
-
subquery_alias = Arel.sql("subquery_for_count")
|
77
|
-
select_value = operation_over_aggregate_column(column_alias, "count", false)
|
78
|
-
|
79
|
-
relation.build_subquery(subquery_alias, select_value)
|
80
|
-
end
|
81
|
-
|
82
|
-
def calculate(operation, column_name)
|
83
|
-
if has_include?(column_name)
|
84
|
-
relation = apply_join_dependency
|
85
|
-
|
86
|
-
if operation.to_s.downcase == "count"
|
87
|
-
unless distinct_value || distinct_select?(column_name || select_for_count)
|
88
|
-
relation.distinct!
|
89
|
-
# CPK
|
90
|
-
# relation.select_values = [ klass.primary_key || table[Arel.star] ]
|
91
|
-
if klass.primary_key.present? && klass.primary_key.is_a?(Array)
|
92
|
-
relation.select_values = klass.primary_key.map do |k|
|
93
|
-
"#{connection.quote_table_name(klass.table_name)}.#{connection.quote_column_name(k)}"
|
94
|
-
end
|
95
|
-
else
|
96
|
-
relation.select_values = [ klass.primary_key || table[Arel.star] ]
|
97
|
-
end
|
98
|
-
end
|
99
|
-
# PostgreSQL: ORDER BY expressions must appear in SELECT list when using DISTINCT
|
100
|
-
relation.order_values = [] if group_values.empty?
|
101
|
-
end
|
102
|
-
|
103
|
-
relation.calculate(operation, column_name)
|
104
|
-
else
|
105
|
-
perform_calculation(operation, column_name)
|
106
|
-
end
|
107
|
-
end
|
108
|
-
end
|
109
|
-
end
|
110
|
-
end
|
1
|
+
module CompositePrimaryKeys
|
2
|
+
module ActiveRecord
|
3
|
+
module Calculations
|
4
|
+
def aggregate_column(column_name)
|
5
|
+
# CPK
|
6
|
+
if column_name.kind_of?(Array)
|
7
|
+
# Note: Test don't seem to run this code?
|
8
|
+
column_name.map do |column|
|
9
|
+
@klass.arel_table[column]
|
10
|
+
end
|
11
|
+
elsif @klass.has_attribute?(column_name) || @klass.attribute_alias?(column_name)
|
12
|
+
@klass.arel_table[column_name]
|
13
|
+
else
|
14
|
+
Arel.sql(column_name == :all ? "*" : column_name.to_s)
|
15
|
+
end
|
16
|
+
end
|
17
|
+
|
18
|
+
def execute_simple_calculation(operation, column_name, distinct) #:nodoc:
|
19
|
+
column_alias = column_name
|
20
|
+
|
21
|
+
# CPK
|
22
|
+
# if operation == "count" && (column_name == :all && distinct || has_limit_or_offset?)
|
23
|
+
# # Shortcut when limit is zero.
|
24
|
+
# return 0 if limit_value == 0
|
25
|
+
#
|
26
|
+
# query_builder = build_count_subquery(spawn, column_name, distinct)
|
27
|
+
if operation == "count"
|
28
|
+
relation = unscope(:order)
|
29
|
+
query_builder = build_count_subquery(spawn, column_name, distinct)
|
30
|
+
else
|
31
|
+
# PostgreSQL doesn't like ORDER BY when there are no GROUP BY
|
32
|
+
relation = unscope(:order).distinct!(false)
|
33
|
+
|
34
|
+
column = aggregate_column(column_name)
|
35
|
+
select_value = operation_over_aggregate_column(column, operation, distinct)
|
36
|
+
select_value.distinct = true if operation == "sum" && distinct
|
37
|
+
|
38
|
+
relation.select_values = [select_value]
|
39
|
+
|
40
|
+
query_builder = relation.arel
|
41
|
+
end
|
42
|
+
|
43
|
+
result = skip_query_cache_if_necessary { @klass.connection.select_all(query_builder) }
|
44
|
+
|
45
|
+
if operation != "count"
|
46
|
+
type = column.try(:type_caster) ||
|
47
|
+
lookup_cast_type_from_join_dependencies(column_name.to_s) || ::ActiveRecord::Type.default_value
|
48
|
+
type = type.subtype if ::ActiveRecord::Enum::EnumType === type
|
49
|
+
end
|
50
|
+
|
51
|
+
type_cast_calculated_value(result.cast_values.first, operation, type) do |value|
|
52
|
+
type = column.try(:type_caster) ||
|
53
|
+
# CPK
|
54
|
+
# lookup_cast_type_from_join_dependencies(column_name.to_s) || Type.default_value
|
55
|
+
lookup_cast_type_from_join_dependencies(column_name.to_s) || ::ActiveRecord::Type.default_value
|
56
|
+
type.deserialize(value)
|
57
|
+
end
|
58
|
+
end
|
59
|
+
|
60
|
+
def build_count_subquery(relation, column_name, distinct)
|
61
|
+
if column_name == :all
|
62
|
+
column_alias = Arel.star
|
63
|
+
# CPK
|
64
|
+
# relation.select_values = [ Arel.sql(FinderMethods::ONE_AS_ONE) ] unless distinct
|
65
|
+
relation.select_values = [ Arel.sql(::ActiveRecord::FinderMethods::ONE_AS_ONE) ] unless distinct
|
66
|
+
elsif column_name.is_a?(Array)
|
67
|
+
column_alias = Arel.star
|
68
|
+
relation.select_values = column_name.map do |column|
|
69
|
+
Arel::Attribute.new(@klass.unscoped.table, column)
|
70
|
+
end
|
71
|
+
else
|
72
|
+
column_alias = Arel.sql("count_column")
|
73
|
+
relation.select_values = [ aggregate_column(column_name).as(column_alias) ]
|
74
|
+
end
|
75
|
+
|
76
|
+
subquery_alias = Arel.sql("subquery_for_count")
|
77
|
+
select_value = operation_over_aggregate_column(column_alias, "count", false)
|
78
|
+
|
79
|
+
relation.build_subquery(subquery_alias, select_value)
|
80
|
+
end
|
81
|
+
|
82
|
+
def calculate(operation, column_name)
|
83
|
+
if has_include?(column_name)
|
84
|
+
relation = apply_join_dependency
|
85
|
+
|
86
|
+
if operation.to_s.downcase == "count"
|
87
|
+
unless distinct_value || distinct_select?(column_name || select_for_count)
|
88
|
+
relation.distinct!
|
89
|
+
# CPK
|
90
|
+
# relation.select_values = [ klass.primary_key || table[Arel.star] ]
|
91
|
+
if klass.primary_key.present? && klass.primary_key.is_a?(Array)
|
92
|
+
relation.select_values = klass.primary_key.map do |k|
|
93
|
+
"#{connection.quote_table_name(klass.table_name)}.#{connection.quote_column_name(k)}"
|
94
|
+
end
|
95
|
+
else
|
96
|
+
relation.select_values = [ klass.primary_key || table[Arel.star] ]
|
97
|
+
end
|
98
|
+
end
|
99
|
+
# PostgreSQL: ORDER BY expressions must appear in SELECT list when using DISTINCT
|
100
|
+
relation.order_values = [] if group_values.empty?
|
101
|
+
end
|
102
|
+
|
103
|
+
relation.calculate(operation, column_name)
|
104
|
+
else
|
105
|
+
perform_calculation(operation, column_name)
|
106
|
+
end
|
107
|
+
end
|
108
|
+
end
|
109
|
+
end
|
110
|
+
end
|
@@ -1,40 +1,40 @@
|
|
1
|
-
module ActiveRecord
|
2
|
-
module Validations
|
3
|
-
class UniquenessValidator
|
4
|
-
def validate_each(record, attribute, value)
|
5
|
-
finder_class = find_finder_class_for(record)
|
6
|
-
value = map_enum_attribute(finder_class, attribute, value)
|
7
|
-
|
8
|
-
relation = build_relation(finder_class, attribute, value)
|
9
|
-
if record.persisted?
|
10
|
-
# CPK
|
11
|
-
if finder_class.primary_key.is_a?(Array)
|
12
|
-
predicate = finder_class.cpk_id_predicate(finder_class.arel_table, finder_class.primary_key, record.id_in_database || record.id)
|
13
|
-
relation = relation.where.not(predicate)
|
14
|
-
elsif finder_class.primary_key
|
15
|
-
relation = relation.where.not(finder_class.primary_key => record.id_in_database)
|
16
|
-
else
|
17
|
-
raise UnknownPrimaryKey.new(finder_class, "Can not validate uniqueness for persisted record without primary key.")
|
18
|
-
end
|
19
|
-
end
|
20
|
-
relation = scope_relation(record, relation)
|
21
|
-
if options[:conditions]
|
22
|
-
conditions = options[:conditions]
|
23
|
-
|
24
|
-
relation = if conditions.arity.zero?
|
25
|
-
relation.instance_exec(&conditions)
|
26
|
-
else
|
27
|
-
relation.instance_exec(record, &conditions)
|
28
|
-
end
|
29
|
-
end
|
30
|
-
|
31
|
-
if relation.exists?
|
32
|
-
error_options = options.except(:case_sensitive, :scope, :conditions)
|
33
|
-
error_options[:value] = value
|
34
|
-
|
35
|
-
record.errors.add(attribute, :taken, **error_options)
|
36
|
-
end
|
37
|
-
end
|
38
|
-
end
|
39
|
-
end
|
40
|
-
end
|
1
|
+
module ActiveRecord
|
2
|
+
module Validations
|
3
|
+
class UniquenessValidator
|
4
|
+
def validate_each(record, attribute, value)
|
5
|
+
finder_class = find_finder_class_for(record)
|
6
|
+
value = map_enum_attribute(finder_class, attribute, value)
|
7
|
+
|
8
|
+
relation = build_relation(finder_class, attribute, value)
|
9
|
+
if record.persisted?
|
10
|
+
# CPK
|
11
|
+
if finder_class.primary_key.is_a?(Array)
|
12
|
+
predicate = finder_class.cpk_id_predicate(finder_class.arel_table, finder_class.primary_key, record.id_in_database || record.id)
|
13
|
+
relation = relation.where.not(predicate)
|
14
|
+
elsif finder_class.primary_key
|
15
|
+
relation = relation.where.not(finder_class.primary_key => record.id_in_database)
|
16
|
+
else
|
17
|
+
raise UnknownPrimaryKey.new(finder_class, "Can not validate uniqueness for persisted record without primary key.")
|
18
|
+
end
|
19
|
+
end
|
20
|
+
relation = scope_relation(record, relation)
|
21
|
+
if options[:conditions]
|
22
|
+
conditions = options[:conditions]
|
23
|
+
|
24
|
+
relation = if conditions.arity.zero?
|
25
|
+
relation.instance_exec(&conditions)
|
26
|
+
else
|
27
|
+
relation.instance_exec(record, &conditions)
|
28
|
+
end
|
29
|
+
end
|
30
|
+
|
31
|
+
if relation.exists?
|
32
|
+
error_options = options.except(:case_sensitive, :scope, :conditions)
|
33
|
+
error_options[:value] = value
|
34
|
+
|
35
|
+
record.errors.add(attribute, :taken, **error_options)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
data/test/fixtures/department.rb
CHANGED
@@ -1,20 +1,20 @@
|
|
1
|
-
class Department < ActiveRecord::Base
|
2
|
-
self.primary_keys = :id, :location_id
|
3
|
-
|
4
|
-
has_many :employees,
|
5
|
-
# We intentionally redefine primary key for test purposes. #455
|
6
|
-
:primary_key => [:id, :location_id],
|
7
|
-
:foreign_key => [:department_id, :location_id]
|
8
|
-
|
9
|
-
has_many :comments, :through => :employees
|
10
|
-
|
11
|
-
has_one :head, :class_name => 'Employee', :autosave => true, :dependent => :delete,
|
12
|
-
# We intentionally redefine primary key for test purposes. #455
|
13
|
-
:primary_key => [:id, :location_id],
|
14
|
-
:foreign_key => [:department_id, :location_id]
|
15
|
-
|
16
|
-
has_one :head_without_autosave, :class_name => 'Employee',
|
17
|
-
# We intentionally redefine primary key for test purposes. #455
|
18
|
-
:primary_key => [:id, :location_id],
|
19
|
-
:foreign_key => [:department_id, :location_id]
|
20
|
-
end
|
1
|
+
class Department < ActiveRecord::Base
|
2
|
+
self.primary_keys = :id, :location_id
|
3
|
+
|
4
|
+
has_many :employees,
|
5
|
+
# We intentionally redefine primary key for test purposes. #455
|
6
|
+
:primary_key => [:id, :location_id],
|
7
|
+
:foreign_key => [:department_id, :location_id]
|
8
|
+
|
9
|
+
has_many :comments, :through => :employees
|
10
|
+
|
11
|
+
has_one :head, :class_name => 'Employee', :autosave => true, :dependent => :delete,
|
12
|
+
# We intentionally redefine primary key for test purposes. #455
|
13
|
+
:primary_key => [:id, :location_id],
|
14
|
+
:foreign_key => [:department_id, :location_id]
|
15
|
+
|
16
|
+
has_one :head_without_autosave, :class_name => 'Employee',
|
17
|
+
# We intentionally redefine primary key for test purposes. #455
|
18
|
+
:primary_key => [:id, :location_id],
|
19
|
+
:foreign_key => [:department_id, :location_id]
|
20
|
+
end
|
@@ -1,18 +1,18 @@
|
|
1
|
-
class RoomAssignment < ActiveRecord::Base
|
2
|
-
self.primary_keys = :student_id, :dorm_id, :room_id
|
3
|
-
belongs_to :student
|
4
|
-
belongs_to :room, :foreign_key => [:dorm_id, :room_id], :primary_key => [:dorm_id, :room_id]
|
5
|
-
validates :student_id, uniqueness: {
|
6
|
-
conditions: ->(record) {
|
7
|
-
where(student_id: record.student_id) # enough just to exercise this code path
|
8
|
-
}
|
9
|
-
}
|
10
|
-
|
11
|
-
before_destroy do |record|
|
12
|
-
puts record
|
13
|
-
end
|
14
|
-
|
15
|
-
after_destroy do |record|
|
16
|
-
puts record
|
17
|
-
end
|
18
|
-
end
|
1
|
+
class RoomAssignment < ActiveRecord::Base
|
2
|
+
self.primary_keys = :student_id, :dorm_id, :room_id
|
3
|
+
belongs_to :student
|
4
|
+
belongs_to :room, :foreign_key => [:dorm_id, :room_id], :primary_key => [:dorm_id, :room_id]
|
5
|
+
validates :student_id, uniqueness: {
|
6
|
+
conditions: ->(record) {
|
7
|
+
where(student_id: record.student_id) # enough just to exercise this code path
|
8
|
+
}
|
9
|
+
}
|
10
|
+
|
11
|
+
before_destroy do |record|
|
12
|
+
puts record
|
13
|
+
end
|
14
|
+
|
15
|
+
after_destroy do |record|
|
16
|
+
puts record
|
17
|
+
end
|
18
|
+
end
|