acts_as_brand_new_copy 1.0.0 → 1.0.1
Sign up to get free protection for your applications and to get access to all the features.
- data/.travis.yml +5 -1
- data/README.md +2 -17
- data/lib/acts_as_brand_new_copy.rb +23 -23
- data/lib/acts_as_brand_new_copy/version.rb +1 -1
- metadata +2 -2
data/.travis.yml
CHANGED
@@ -1,5 +1,9 @@
|
|
1
1
|
language: ruby
|
2
2
|
rvm:
|
3
|
-
- "1.8.7"
|
4
3
|
- "1.9.3"
|
4
|
+
- "2.0.0"
|
5
5
|
script: bundle exec rspec spec
|
6
|
+
before_install:
|
7
|
+
- curl -O http://mirrors.kernel.org/ubuntu/pool/main/s/sqlite3/libsqlite3-0_3.7.13-1_amd64.deb
|
8
|
+
- curl -O http://mirrors.kernel.org/ubuntu/pool/main/s/sqlite3/sqlite3_3.7.13-1_amd64.deb
|
9
|
+
- sudo dpkg -i libsqlite3-0_3.7.13-1_amd64.deb sqlite3_3.7.13-1_amd64.deb
|
data/README.md
CHANGED
@@ -5,24 +5,9 @@
|
|
5
5
|
|
6
6
|
Copy an active record with its associated records are not easy.
|
7
7
|
|
8
|
-
For example, if we have defined
|
8
|
+
For example, if we have defined following classes:
|
9
9
|
|
10
10
|
```ruby
|
11
|
-
class StudentTeacherAssignment < ActiveRecord::Base
|
12
|
-
belongs_to :teacher
|
13
|
-
belongs_to :student
|
14
|
-
end
|
15
|
-
|
16
|
-
class GradeTeacherAssignment < ActiveRecord::Base
|
17
|
-
belongs_to :grade
|
18
|
-
belongs_to :teacher
|
19
|
-
end
|
20
|
-
|
21
|
-
class GradeStudentAssignment < ActiveRecord::Base
|
22
|
-
belongs_to :grade
|
23
|
-
belongs_to :student
|
24
|
-
end
|
25
|
-
|
26
11
|
class Grade < ActiveRecord::Base
|
27
12
|
has_and_belongs_to_many :teachers, :join_table => ::GradeTeacherAssignment.table_name
|
28
13
|
has_and_belongs_to_many :students, :join_table => ::GradeStudentAssignment.table_name
|
@@ -48,7 +33,7 @@ class Score < ActiveRecord::Base
|
|
48
33
|
end
|
49
34
|
```
|
50
35
|
|
51
|
-
Can you copy a grade with its teachers and students to another grade in a few lines of code?
|
36
|
+
Can you copy a grade with its teachers and students to another grade in a few lines of code, keeping the relationships between teachers and students?
|
52
37
|
To me, it's no, consequently acts_as_brand_new_copy was born.
|
53
38
|
|
54
39
|
## Usage
|
@@ -5,18 +5,16 @@ module ActsAsBrandNewCopy
|
|
5
5
|
|
6
6
|
class BrandNewCopyBuilder
|
7
7
|
|
8
|
-
def initialize(
|
9
|
-
@hash_origin =
|
10
|
-
@hash_copy =
|
8
|
+
def initialize(serialized_hash)
|
9
|
+
@hash_origin = serialized_hash
|
10
|
+
@hash_copy = JSON.parse(serialized_hash.to_json) # a way to do deep clone
|
11
11
|
@save_order = calculate_save_order
|
12
12
|
@instances = extract_instances
|
13
13
|
@queue = prepare_copy_queue
|
14
14
|
@full_context = {
|
15
|
-
:
|
16
|
-
:
|
17
|
-
:
|
18
|
-
:save_queue => @queue,
|
19
|
-
:instances => @instances
|
15
|
+
:save_order => @save_order,
|
16
|
+
:save_queue => @queue,
|
17
|
+
:instances => @instances
|
20
18
|
}
|
21
19
|
end
|
22
20
|
|
@@ -44,6 +42,13 @@ module ActsAsBrandNewCopy
|
|
44
42
|
@instances.values
|
45
43
|
end
|
46
44
|
|
45
|
+
def new_id(klass_name, old_id)
|
46
|
+
copy_object = find_object_by_old_id(klass_name, old_id)
|
47
|
+
return nil if copy_object.nil?
|
48
|
+
raise 'copy object not saved to db!' if copy_object['id'] == copy_object['id_before_copy']
|
49
|
+
copy_object['id']
|
50
|
+
end
|
51
|
+
|
47
52
|
private
|
48
53
|
|
49
54
|
def invoke_callback_recursively(hash_origin_array, callbacks)
|
@@ -203,7 +208,7 @@ module ActsAsBrandNewCopy
|
|
203
208
|
|
204
209
|
def do_insert(klass, columns, hash_copies)
|
205
210
|
connection = klass.connection
|
206
|
-
|
211
|
+
value_list = hash_copies.map do |hash_copy|
|
207
212
|
quoted_copy_values = columns.map do |column|
|
208
213
|
case column.name
|
209
214
|
when 'updated_at', 'created_at'
|
@@ -212,9 +217,12 @@ module ActsAsBrandNewCopy
|
|
212
217
|
connection.quote(hash_copy[column.name], column)
|
213
218
|
end
|
214
219
|
end
|
215
|
-
"(#{quoted_copy_values.join(',')})"
|
216
|
-
end
|
217
|
-
|
220
|
+
"(#{quoted_copy_values.join(', ')})"
|
221
|
+
end
|
222
|
+
column_list = columns.map do |column|
|
223
|
+
connection.quote_column_name(column.name)
|
224
|
+
end
|
225
|
+
result = connection.execute("INSERT INTO #{connection.quote_table_name(klass.table_name)} (#{column_list.join(', ')}) VALUES #{value_list.join(', ')}")
|
218
226
|
connection.last_inserted_id(result)
|
219
227
|
end
|
220
228
|
|
@@ -245,13 +253,6 @@ module ActsAsBrandNewCopy
|
|
245
253
|
@instances[object_key(klass_name, old_id)]
|
246
254
|
end
|
247
255
|
|
248
|
-
def new_id(klass_name, old_id)
|
249
|
-
copy_object = find_object_by_old_id(klass_name, old_id)
|
250
|
-
return nil if copy_object.nil?
|
251
|
-
raise 'copy object not saved to db!' if copy_object['id'] == copy_object['id_before_copy']
|
252
|
-
copy_object['id']
|
253
|
-
end
|
254
|
-
|
255
256
|
def update_object_by_old_id(klass_name, old_id, new_attributes)
|
256
257
|
copy_object = find_object_by_old_id(klass_name, old_id)
|
257
258
|
new_attributes.each_pair do |key, value|
|
@@ -425,14 +426,13 @@ module ActsAsBrandNewCopy
|
|
425
426
|
|
426
427
|
eager_loaded_self = self.class.includes(final_options[:associations]).find(id)
|
427
428
|
|
428
|
-
|
429
|
-
hash_copy = JSON.parse(hash_origin.to_json) # a way to do deep clone
|
429
|
+
serialized_hash = eager_loaded_self.serialize_hash_for_copy(final_options[:associations])
|
430
430
|
|
431
|
-
builder = BrandNewCopyBuilder.new(
|
431
|
+
builder = BrandNewCopyBuilder.new(serialized_hash)
|
432
432
|
builder.invoke_callback(final_options[:callbacks])
|
433
433
|
builder.save
|
434
434
|
|
435
|
-
return
|
435
|
+
return builder.new_id(self.class.name, self.id)
|
436
436
|
end
|
437
437
|
end
|
438
438
|
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: acts_as_brand_new_copy
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 1.0.
|
4
|
+
version: 1.0.1
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2013-11-
|
12
|
+
date: 2013-11-25 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: bundler
|