rails_core_extensions 0.0.1 → 0.1.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 2f9fbc63db383e76902baaee3cd6a097777bcc11
4
- data.tar.gz: de5b0b677d9654fa23281fc5f46a0a8616808775
3
+ metadata.gz: 75e544c0a483d1b86ad8520255bb606a5f933aa1
4
+ data.tar.gz: 77c1fc668e12ea84ec69ede1991f5a339513b90f
5
5
  SHA512:
6
- metadata.gz: 89904b0e0effe8e6aacb48a2bfe32b397dabd83fc0bf55c5d283b58097ae63fa1a7c61245c2a9be441c8450445881653fde64567166051a52337ef41ba25a49c
7
- data.tar.gz: 34bc41008e7fdd30af24043d062c7267ad62ba0d02536e673083b43972c46a62df0cdbe156e61c5d860a254771df40c83e3e396ac8199c8f0fc365a8d146871f
6
+ metadata.gz: 3ffbf789ea526bf8a86705daa487a620a9ed3210f4a2d7f7ac6b2e19348dd3c4c23541f055b5e088f8e4b2d96e24e50e9ac31c9a6f6abcf899d6660dd0ddde66
7
+ data.tar.gz: 9c747e644c79d6ea9db7c427afd4b98fd44dccc7f75f937667f6437f545f055b326093561243596229c955f496921e7d5d93afd3c7e7aeb530e62a74c411b9e8
@@ -5,6 +5,7 @@ script: "bundle exec rake spec"
5
5
  gemfile:
6
6
  - gemfiles/rails3.gemfile
7
7
  - gemfiles/rails4.gemfile
8
+ - gemfiles/rails5.gemfile
8
9
  notifications:
9
10
  email:
10
11
  - support@travellink.com.au
@@ -0,0 +1,8 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0
4
+
5
+ * Add rails 5 support
6
+ * Refactor clone_excluding to enable rails 5 support
7
+ * Extract transfer_records to class
8
+ * Rename enum to enum_int to be rails 4/5 compatible
@@ -2,12 +2,5 @@ source :rubygems
2
2
  gemspec :path => '../'
3
3
 
4
4
  group :development, :test do
5
- gem 'rake', '~> 0.9.2'
6
- gem 'rdoc', '~> 3.12'
7
- gem 'rspec'
8
- gem 'simplecov'
9
- gem 'simplecov-rcov'
10
- gem 'sqlite3'
11
- gem 'activesupport', '~> 3.2.0'
12
5
  gem 'activerecord', '~> 3.2.0'
13
6
  end
@@ -2,13 +2,5 @@ source :rubygems
2
2
  gemspec :path => '../'
3
3
 
4
4
  group :development, :test do
5
- gem 'rake', '~> 0.9.2'
6
- gem 'rdoc', '~> 3.12'
7
- gem 'rspec'
8
- gem 'simplecov'
9
- gem 'simplecov-rcov'
10
- gem 'sqlite3'
11
- gem 'activesupport', '~> 4.0'
12
5
  gem 'activerecord', '~> 4.0'
13
6
  end
14
-
@@ -0,0 +1,6 @@
1
+ source :rubygems
2
+ gemspec :path => '../'
3
+
4
+ group :development, :test do
5
+ gem 'activerecord', '~> 5.0'
6
+ end
@@ -6,6 +6,7 @@ module RailsCoreExtensions
6
6
  require 'rails_core_extensions/breadcrumb'
7
7
  require 'rails_core_extensions/position_initializer'
8
8
  require 'rails_core_extensions/time_with_zone'
9
+ require 'rails_core_extensions/transfer_records'
9
10
  require 'rails_core_extensions/active_support_concern'
10
11
  require 'rails_core_extensions/concurrency'
11
12
 
@@ -1,5 +1,4 @@
1
1
  module ActiveRecordCloning
2
-
3
2
  def self.included(base)
4
3
  base.extend(ClassMethods)
5
4
  end
@@ -27,6 +26,26 @@ module ActiveRecordCloning
27
26
  cloned_attributes_hash[:exclude] = attributes.map(&:to_sym)
28
27
  end
29
28
 
29
+ def clones_attributes_reset
30
+ @cloned_attributes = nil
31
+ end
32
+
33
+ def exclude_attributes(cloned, excludes)
34
+ excluded_attributes(excludes).each do |attr|
35
+ cloned.send("#{attr}=", nil)
36
+ end
37
+ end
38
+
39
+ def excluded_attributes(excludes)
40
+ all_attributes = attribute_names.map(&:to_sym)
41
+ included_attributes = if attributes_included_in_cloning.empty?
42
+ all_attributes
43
+ else
44
+ all_attributes & attributes_included_in_cloning
45
+ end
46
+ all_attributes - included_attributes + attributes_excluded_from_cloning + excludes
47
+ end
48
+
30
49
  protected
31
50
 
32
51
  def cloned_attributes_hash
@@ -39,43 +58,12 @@ module ActiveRecordCloning
39
58
 
40
59
  end
41
60
 
42
- module InstanceMethods
43
-
44
- def self.included(base)
45
- base.class_eval %q{
46
- alias_method :base_clone_attributes, :clone_attributes
47
- def clone_attributes(reader_method = :read_attribute, attributes = {})
48
- allowed = cloned_attributes
49
- base_clone_attributes(reader_method, attributes).delete_if { |k,v| !allowed.include?(k.to_sym) }
50
- end
51
- }
52
- end
53
-
54
- def clone_excluding(excludes=[])
55
- method = ActiveRecord::Base.instance_methods(false).include?(:clone) ? :clone : :dup
56
- cloned = send(method)
57
-
58
- excludes ||= []
59
- excludes = [excludes] unless excludes.is_a?(Enumerable)
60
-
61
- excludes.each do |excluded_attr|
62
- attr_writer = (excluded_attr.to_s + '=').to_sym
63
- cloned.send attr_writer, nil
64
- end
65
-
66
- cloned
67
- end
68
-
69
- private
70
-
71
- def cloned_attributes
72
- included_attributes = if self.class.attributes_included_in_cloning.empty?
73
- attribute_names.map(&:to_sym)
74
- else
75
- attribute_names.map(&:to_sym) & self.class.attributes_included_in_cloning
76
- end
77
- included_attributes - self.class.attributes_excluded_from_cloning
78
- end
61
+ def clone_excluding(excludes=[])
62
+ method = ActiveRecord::Base.instance_methods(false).include?(:clone) ? :clone : :dup
63
+ cloned = send(method)
64
+ excludes ||= []
65
+ excludes = [excludes] unless excludes.is_a?(Enumerable)
66
+ self.class.exclude_attributes(cloned, excludes)
67
+ cloned
79
68
  end
80
-
81
69
  end
@@ -2,7 +2,7 @@ module ActiveRecordExtensions
2
2
  def self.included(base)
3
3
  base.extend ClassMethods
4
4
  end
5
-
5
+
6
6
  module ClassMethods
7
7
  # Like establish_connection but postfixes the key with the rails environment
8
8
  # e.g. database('hello') in development will look for the database
@@ -41,15 +41,11 @@ module ActiveRecordExtensions
41
41
  rec
42
42
  end
43
43
  end
44
-
45
- def enum(field, values, options = {})
44
+
45
+ def enum_int(field, values, options = {})
46
46
  const_set("#{field.to_s.upcase}_OPTIONS", values)
47
-
48
- select_options = if values.is_a?(Array)
49
- values.map.with_index{|v, i| [v.to_s.humanize, i]}
50
- elsif values.is_a?(Hash)
51
- values.values.map.with_index{|v, i| [v, i]}
52
- end
47
+
48
+ select_options = values.map.with_index{|v, i| [v.to_s.humanize, i]}
53
49
  const_set("#{field.to_s.upcase}_SELECT_OPTIONS", select_options)
54
50
 
55
51
  values.each.with_index do |value, i|
@@ -90,7 +86,6 @@ module ActiveRecordExtensions
90
86
  end
91
87
  end
92
88
 
93
-
94
89
  def position_helpers_for(*collections)
95
90
  collections.each do |collection|
96
91
  class_eval <<-EVAL
@@ -114,7 +109,6 @@ module ActiveRecordExtensions
114
109
  end
115
110
  end
116
111
 
117
-
118
112
  # Validates presence of -- but works on parent within accepts_nested_attributes
119
113
  #
120
114
  def validates_presence_of_parent(foreign_key)
@@ -126,7 +120,6 @@ module ActiveRecordExtensions
126
120
  end
127
121
  end
128
122
 
129
-
130
123
  # Run a block, being respectful of connection pools
131
124
  #
132
125
  # Useful for when you're not in the standard rails request process,
@@ -150,27 +143,20 @@ module ActiveRecordExtensions
150
143
  # and also returns connections to the pool cached by threads that are no
151
144
  # longer alive.
152
145
  ActiveRecord::Base.clear_active_connections!
153
-
154
146
  end
155
147
 
156
-
157
148
  def translate(key, options = {})
158
149
  klass = self
159
150
  klass = klass.superclass while klass.superclass != ActiveRecord::Base
160
151
  I18n.translate key, options.merge(:scope => klass.name.tableize.singularize)
161
152
  end
162
153
 
163
-
164
154
  def t(key, options = {})
165
155
  self.translate(key, options)
166
156
  end
167
-
168
157
  end
169
158
 
170
-
171
159
  module InstanceMethods
172
-
173
-
174
160
  def all_errors
175
161
  errors_hash = {}
176
162
  self.errors.each do |attr, msg|
@@ -183,46 +169,26 @@ module ActiveRecordExtensions
183
169
  errors_hash
184
170
  end
185
171
 
186
-
187
172
  def to_drop
188
173
  @drop_class ||= (self.class.name+'Drop').constantize
189
174
  @drop_class.new(self)
190
175
  end
191
176
  alias_method :to_liquid, :to_drop
192
177
 
193
-
194
178
  # A unique id - even if you are unsaved!
195
179
  def unique_id
196
180
  id || @generated_dom_id || (@generated_dom_id = Time.now.to_f.to_s.gsub('.', '_'))
197
181
  end
198
182
 
199
-
200
183
  #getting audits
201
184
  def audit_log
202
185
  return (self.methods.include?('audits') ? self.audits : [])
203
186
  end
204
187
 
205
-
206
-
207
188
  private
208
189
 
209
190
  def t(key, options = {})
210
191
  self.class.translate(key, options)
211
192
  end
212
-
213
-
214
- def transfer_records(klass, objects, options = {})
215
- record_ids = objects.flat_map { |o|
216
- o.send(klass.name.underscore + '_ids')
217
- }
218
- unless record_ids.empty?
219
- options[:foreign_key] ||= self.class.name.underscore + '_id'
220
- update_options = options.except(:foreign_key)
221
- update_options[options[:foreign_key]] = id
222
- klass.where(id: record_ids).update_all(update_options)
223
- end
224
- end
225
-
226
193
  end
227
-
228
194
  end
@@ -0,0 +1,21 @@
1
+ module RailsCoreExtensions
2
+ class TransferRecords
3
+ def initialize(parent, klass, options = {})
4
+ @parent = parent
5
+ @klass = klass
6
+ @options = options
7
+ end
8
+
9
+ def transfer_from(objects)
10
+ record_ids = objects.flat_map { |o|
11
+ o.send(@klass.name.underscore + '_ids')
12
+ }
13
+ unless record_ids.empty?
14
+ @options[:foreign_key] ||= @parent.class.name.underscore + '_id'
15
+ update_options = @options.except(:foreign_key)
16
+ update_options[@options[:foreign_key]] = @parent.id
17
+ @klass.where(id: record_ids).update_all(update_options)
18
+ end
19
+ end
20
+ end
21
+ end
@@ -1,3 +1,3 @@
1
1
  module RailsCoreExtensions
2
- VERSION = '0.0.1'
2
+ VERSION = '0.1.0'
3
3
  end
@@ -19,8 +19,8 @@ Gem::Specification.new do |spec|
19
19
  spec.test_files = spec.files.grep(%r{^(test|spec|features)/})
20
20
  spec.require_paths = ['lib']
21
21
 
22
- spec.add_dependency 'activerecord', ['>= 2.3.0', '< 5.0.0']
23
- spec.add_dependency 'actionpack', ['>= 2.3.0', '< 5.0.0']
22
+ spec.add_dependency 'activerecord', ['>= 2.3.0']
23
+ spec.add_dependency 'actionpack', ['>= 2.3.0']
24
24
 
25
25
  spec.add_development_dependency 'bundler', '~> 1.3'
26
26
  spec.add_development_dependency 'rake'
@@ -2,24 +2,31 @@ require 'spec_helper'
2
2
 
3
3
  require 'rails_core_extensions/sortable'
4
4
 
5
- connect_to_sqlite
6
-
7
5
  describe RailsCoreExtensions::Sortable do
8
- before do
9
- Model = Class.new(ActiveRecord::Base) do
6
+ let(:model_class) {
7
+ Class.new(ActiveRecord::Base) do
10
8
  default_scope -> { order(:name) }
11
9
  end
12
- @one = Model.create!(name: 'One', position: 1, category_id: 1)
13
- @two = Model.create!(name: 'Two', position: 2, category_id: 1)
14
- @thr = Model.create!(name: 'Thr', position: 3, category_id: 2)
10
+ }
11
+
12
+ before do
13
+ connect_to_sqlite
14
+
15
+ stub_const 'Model', model_class
16
+
17
+ models
15
18
  end
16
19
 
20
+ let(:one) { Model.create!(name: 'One', position: 1, category_id: 1) }
21
+ let(:two) { Model.create!(name: 'Two', position: 2, category_id: 1) }
22
+ let(:thr) { Model.create!(name: 'Thr', position: 3, category_id: 2) }
23
+ let(:models) { [one, two, thr] }
24
+
17
25
  after do
18
- Model.delete_all
19
- Object.send(:remove_const, 'Model')
26
+ models.each(&:destroy)
20
27
  end
21
28
 
22
- let(:params) { { model_body: [@one.id, @thr.id, @two.id] } }
29
+ let(:params) { { model_body: [one.id, thr.id, two.id] } }
23
30
  subject { RailsCoreExtensions::Sortable.new(params, 'models') }
24
31
 
25
32
  describe 'when unscoped' do
@@ -35,14 +42,14 @@ describe RailsCoreExtensions::Sortable do
35
42
  let(:scope) { Model.where(category_id: 1).reorder(:position) }
36
43
  specify { expect(scope.pluck(:name)).to eq %w(One Two) }
37
44
 
38
- let(:params) { { category_id: 1, scope: :category_id, model_1_body: [@two.id, @one.id] } }
45
+ let(:params) { { category_id: 1, scope: :category_id, model_1_body: [two.id, one.id] } }
39
46
  it 'should correctly sort' do
40
47
  subject.sort
41
48
  expect(scope.pluck(:name)).to eq %w(Two One)
42
49
  end
43
50
 
44
51
  describe 'when params scoped differently' do
45
- let(:params) { { category_id: 1, scope: :category_id, category_1_body: [@two.id, @one.id] } }
52
+ let(:params) { { category_id: 1, scope: :category_id, category_1_body: [two.id, one.id] } }
46
53
  it 'should correctly sort' do
47
54
  subject.sort
48
55
  expect(scope.pluck(:name)).to eq %w(Two One)
@@ -0,0 +1,91 @@
1
+ require 'spec_helper'
2
+
3
+ describe ActiveRecordCloning do
4
+ let(:attrs) {
5
+ {
6
+ name: 'Bill',
7
+ age: '50',
8
+ position: 6,
9
+ category_id: 1
10
+ }
11
+ }
12
+ let(:record) { model_class.create!(attrs) }
13
+ let(:model_class) { Class.new(ActiveRecord::Base) { self.table_name = 'models' } }
14
+
15
+ before do
16
+ connect_to_sqlite
17
+ ActiveRecord::Base.send :include, ActiveRecordCloning
18
+ stub_const 'Model', model_class
19
+ Model.clones_attributes_reset
20
+ end
21
+
22
+ after do
23
+ Model.delete_all
24
+ end
25
+
26
+ context 'cloned attributes should clone everything' do
27
+ subject(:clone) { record.clone }
28
+ specify { expect(subject.name).to eq 'Bill' }
29
+ specify { expect(subject.age).to eq '50' }
30
+ specify { expect(subject.position).to eq 6 }
31
+ specify { expect(subject.category_id).to eq 1 }
32
+ end
33
+
34
+ context 'when model is standard' do
35
+ context 'clone excluding should exclude' do
36
+ subject(:clone_excluding) { record.clone_excluding(:category_id) }
37
+ specify { expect(subject.name).to eq 'Bill' }
38
+ specify { expect(subject.age).to eq '50' }
39
+ specify { expect(subject.position).to eq 6 }
40
+ specify { expect(subject.category_id).to be nil }
41
+ end
42
+ end
43
+
44
+ context 'when model excludes attributes by default' do
45
+ before do
46
+ model_class.class_eval do
47
+ clones_attributes_except :category_id
48
+ end
49
+ end
50
+
51
+ context 'clone excluding should exclude' do
52
+ subject(:clone_excluding) { record.clone_excluding }
53
+ specify { expect(subject.name).to eq 'Bill' }
54
+ specify { expect(subject.age).to eq '50' }
55
+ specify { expect(subject.position).to eq 6 }
56
+ specify { expect(subject.category_id).to be nil }
57
+ end
58
+
59
+ context 'clone excluding should exclude additional arguments' do
60
+ subject(:clone_excluding) { record.clone_excluding(:position) }
61
+ specify { expect(subject.name).to eq 'Bill' }
62
+ specify { expect(subject.age).to eq '50' }
63
+ specify { expect(subject.position).to eq nil }
64
+ specify { expect(subject.category_id).to be nil }
65
+ end
66
+ end
67
+
68
+ context 'when model includes attributes by default' do
69
+ before do
70
+ model_class.class_eval do
71
+ clones_attributes :name, :age
72
+ end
73
+ end
74
+
75
+ context 'clone excluding should exclude' do
76
+ subject(:clone_excluding) { record.clone_excluding }
77
+ specify { expect(subject.name).to eq 'Bill' }
78
+ specify { expect(subject.age).to eq '50' }
79
+ specify { expect(subject.position).to eq nil }
80
+ specify { expect(subject.category_id).to be nil }
81
+ end
82
+
83
+ context 'clone excluding should exclude additional arguments' do
84
+ subject(:clone_excluding) { record.clone_excluding(:age) }
85
+ specify { expect(subject.name).to eq 'Bill' }
86
+ specify { expect(subject.age).to eq nil }
87
+ specify { expect(subject.position).to eq nil }
88
+ specify { expect(subject.category_id).to be nil }
89
+ end
90
+ end
91
+ end
@@ -1,14 +1,15 @@
1
1
  require 'spec_helper'
2
2
 
3
- connect_to_sqlite
4
-
5
3
  describe "optional_fields" do
6
- before do
7
- Model = Class.new(ActiveRecord::Base) do
4
+ let(:model_class) {
5
+ Class.new(ActiveRecord::Base) do
8
6
  optional_fields :name, :age, -> { [:age] }
9
7
  end
8
+ }
9
+
10
+ before do
11
+ stub_const 'Model', model_class
10
12
  end
11
- after { Object.send(:remove_const, 'Model') }
12
13
 
13
14
  it 'should know what fields are optional' do
14
15
  expect(Model).to be_age_enabled
@@ -21,13 +22,56 @@ describe "optional_fields" do
21
22
  end
22
23
  end
23
24
 
24
- describe "ActiveRecord::Base" do
25
- before(:all) { Model = Class.new(ActiveRecord::Base) }
26
- after (:all) { Object.send(:remove_const, 'Model') }
27
-
25
+ describe 'enum_int' do
26
+ let(:model_class) {
27
+ Class.new(ActiveRecord::Base) do
28
+ enum_int :category_id, %w(one two thr)
29
+ end
30
+ }
28
31
  before do
29
- @mock_model = double("mock model")
32
+ connect_to_sqlite
33
+ stub_const 'Model', model_class
34
+ end
35
+ let(:one) { Model.new(category_id: 'one') }
36
+
37
+ it 'should define constants' do
38
+ expect(Model::CATEGORY_ID_OPTIONS).to eq %w(one two thr)
39
+ expect(Model::CATEGORY_ID_ONE).to eq 0
40
+ expect(Model::CATEGORY_ID_TWO).to eq 1
41
+ expect(Model::CATEGORY_ID_THR).to eq 2
42
+ end
43
+
44
+ it 'should define methods' do
45
+ expect(one.category_id_one?).to be true
46
+ expect(one.category_id_two?).to be false
47
+ expect(one.category_id_thr?).to be false
48
+ end
49
+
50
+ it 'should define select options' do
51
+ expect(Model::CATEGORY_ID_SELECT_OPTIONS).to eq([
52
+ ['One', 0], ['Two', 1], ['Thr', 2]
53
+ ])
54
+ end
55
+
56
+ context 'when short name' do
57
+ let(:model_class) {
58
+ Class.new(ActiveRecord::Base) do
59
+ enum_int :category_id, %w(one two thr), short_name: true
60
+ end
61
+ }
62
+
63
+ it 'should define methods' do
64
+ expect(one.one?).to be true
65
+ expect(one.two?).to be false
66
+ expect(one.thr?).to be false
67
+ end
30
68
  end
69
+ end
70
+
71
+ describe "ActiveRecord::Base" do
72
+ let(:mock_model) { double }
73
+ let(:model_class) { Class.new(ActiveRecord::Base) }
74
+ before { stub_const 'Model', model_class }
31
75
 
32
76
  it "should create a new record if new_or_update! is passed a hash without an :id" do
33
77
  attributes = {:fake_column => 'nothing really'}
@@ -37,11 +81,10 @@ describe "ActiveRecord::Base" do
37
81
 
38
82
  it "should update record if new_or_update! is passed hash with :id" do
39
83
  attributes = {:fake_column => 'nothing really', :id => 1}
40
- expect(Model).to receive(:find) { @mock_model }
41
- expect(@mock_model).to receive(:update_attributes!)
84
+ expect(Model).to receive(:find) { mock_model }
85
+ expect(mock_model).to receive(:update_attributes!)
42
86
  Model.new_or_update!(attributes)
43
87
  end
44
-
45
88
  end
46
89
 
47
90
  describe RailsCoreExtensions::ActionControllerSortable do
@@ -60,67 +103,36 @@ describe RailsCoreExtensions::ActionControllerSortable do
60
103
  end
61
104
 
62
105
  describe ActiveRecordExtensions do
63
- class Parent < ActiveRecord::Base
64
- has_many :children
65
- def transfer_children_from(old_parent)
66
- transfer_records(Child, [old_parent])
67
- end
68
- end
69
- class Child < ActiveRecord::Base
70
- belongs_to :parent
71
- end
72
-
73
- let(:old) { Parent.create! }
74
- let(:new) { Parent.create! }
75
-
76
- before do
77
- new.children.create!
78
- old.children.create!
79
- end
80
-
81
- after do
82
- Parent.delete_all
83
- Child.delete_all
84
- end
85
-
86
- it 'should transfer records' do
87
- expect(new.children.size).to eq 1
88
- expect(old.children.size).to eq 1
89
- new.transfer_children_from(old)
90
- expect(new.reload.children.size).to eq 2
91
- expect(old.reload.children.size).to eq 0
92
- end
93
- end
94
-
95
- describe ActiveRecordExtensions do
96
- before(:all) do
97
- Model = Class.new(ActiveRecord::Base) do
106
+ let(:model_class) {
107
+ Class.new(ActiveRecord::Base) do
98
108
  cache_all_attributes :by => 'name'
99
109
  end
100
- end
101
- after (:all) { Object.send(:remove_const, 'Model') }
110
+ }
111
+ let(:first) { Model.create!(:name => 'First') }
112
+ let(:second) { Model.create!(:name => 'Second') }
113
+ let(:expected) {
114
+ {
115
+ 'First' => first.attributes,
116
+ 'Second' => second.attributes
117
+ }
118
+ }
102
119
 
103
120
  before do
121
+ connect_to_sqlite
122
+ stub_const 'Model', model_class
104
123
  allow(Model).to receive(:cache) { ActiveSupport::Cache::MemoryStore.new }
105
124
  allow(Model).to receive(:should_cache?) { true }
106
- end
107
-
108
- after do
109
- Model.delete_all
125
+ [first, second]
110
126
  end
111
127
 
112
128
  it 'should cache all attributes' do
113
- @first = Model.create!(:name => 'First')
114
- @second = Model.create!(:name => 'Second')
115
-
116
- expected = {'First' => @first.attributes, 'Second' => @second.attributes}
117
-
118
129
  # Test underlying generate attributes hash method works
119
130
  expect(Model.generate_attributes_hash).to eq expected
120
131
  expect(Model.attribute_cache).to eq expected
121
132
 
122
133
  # Test after save/destroy it updates
123
- @first.destroy
124
- expect(Model.attribute_cache).to eq 'Second' => @second.attributes
134
+ first.destroy
135
+ expect(Model.attribute_cache).to eq 'Second' => second.attributes
136
+ second.destroy # Clean up after
125
137
  end
126
138
  end
@@ -1,6 +1,7 @@
1
1
  require 'rails_core_extensions/breadcrumb'
2
2
 
3
3
  require 'action_view'
4
+ require 'action_view/helpers'
4
5
 
5
6
  describe RailsCoreExtensions::Breadcrumb do
6
7
  before do
@@ -1,16 +1,15 @@
1
1
  require 'spec_helper'
2
2
 
3
- connect_to_sqlite
4
-
5
3
  describe RailsCoreExtensions::PositionInitializer, 'When repositioning' do
6
4
  class Child < ActiveRecord::Base; end
7
5
 
8
6
  before do
7
+ connect_to_sqlite
9
8
  Child.create!(parent_id: 1, name: 'A child')
10
9
  end
11
10
 
12
11
  after do
13
- Child.delete_all
12
+ child.destroy
14
13
  end
15
14
 
16
15
  subject { RailsCoreExtensions::PositionInitializer.new(Child, :parent_id) }
@@ -34,6 +33,11 @@ describe RailsCoreExtensions::PositionInitializer, 'When repositioning' do
34
33
  Child.create!(parent_id: 1, name: 'Third child')
35
34
  end
36
35
 
36
+ after do
37
+ child2.destroy
38
+ child3.destroy
39
+ end
40
+
37
41
  context 'when re-positioned' do
38
42
  before { subject.positionalize }
39
43
 
@@ -23,6 +23,8 @@ end
23
23
 
24
24
  DB_FILE = 'tmp/test_db'
25
25
  def connect_to_sqlite
26
+ return if ActiveRecord::Base.connected?
27
+
26
28
  FileUtils.mkdir_p File.dirname(DB_FILE)
27
29
  FileUtils.rm_f DB_FILE
28
30
 
@@ -1,4 +1,4 @@
1
- MINIMUM_COVERAGE = 74.3
1
+ MINIMUM_COVERAGE = 79.4
2
2
 
3
3
  unless ENV['COVERAGE'] == 'off'
4
4
  require 'simplecov'
@@ -0,0 +1,36 @@
1
+ require 'spec_helper'
2
+
3
+ describe RailsCoreExtensions::TransferRecords do
4
+ class Parent < ActiveRecord::Base
5
+ has_many :children, dependent: :destroy
6
+ def transfer_children_from(old_parent)
7
+ RailsCoreExtensions::TransferRecords.new(self, Child).transfer_from([old_parent])
8
+ end
9
+ end
10
+ class Child < ActiveRecord::Base
11
+ belongs_to :parent
12
+ end
13
+
14
+ let(:old) { Parent.create! }
15
+ let(:new) { Parent.create! }
16
+
17
+ before do
18
+ connect_to_sqlite
19
+ new.children.create!
20
+ old.children.create!
21
+ end
22
+
23
+ after do
24
+ old.destroy
25
+ new.destroy
26
+ end
27
+
28
+ it 'should transfer records' do
29
+ expect(new.children.size).to eq 1
30
+ expect(old.children.size).to eq 1
31
+ new.transfer_children_from(old)
32
+ expect(new.reload.children.size).to eq 2
33
+ expect(old.reload.children.size).to eq 0
34
+ end
35
+ end
36
+
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rails_core_extensions
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.0.1
4
+ version: 0.1.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Michael Noack
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2016-06-17 00:00:00.000000000 Z
12
+ date: 2016-07-28 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: activerecord
@@ -18,9 +18,6 @@ dependencies:
18
18
  - - ">="
19
19
  - !ruby/object:Gem::Version
20
20
  version: 2.3.0
21
- - - "<"
22
- - !ruby/object:Gem::Version
23
- version: 5.0.0
24
21
  type: :runtime
25
22
  prerelease: false
26
23
  version_requirements: !ruby/object:Gem::Requirement
@@ -28,9 +25,6 @@ dependencies:
28
25
  - - ">="
29
26
  - !ruby/object:Gem::Version
30
27
  version: 2.3.0
31
- - - "<"
32
- - !ruby/object:Gem::Version
33
- version: 5.0.0
34
28
  - !ruby/object:Gem::Dependency
35
29
  name: actionpack
36
30
  requirement: !ruby/object:Gem::Requirement
@@ -38,9 +32,6 @@ dependencies:
38
32
  - - ">="
39
33
  - !ruby/object:Gem::Version
40
34
  version: 2.3.0
41
- - - "<"
42
- - !ruby/object:Gem::Version
43
- version: 5.0.0
44
35
  type: :runtime
45
36
  prerelease: false
46
37
  version_requirements: !ruby/object:Gem::Requirement
@@ -48,9 +39,6 @@ dependencies:
48
39
  - - ">="
49
40
  - !ruby/object:Gem::Version
50
41
  version: 2.3.0
51
- - - "<"
52
- - !ruby/object:Gem::Version
53
- version: 5.0.0
54
42
  - !ruby/object:Gem::Dependency
55
43
  name: bundler
56
44
  requirement: !ruby/object:Gem::Requirement
@@ -217,12 +205,14 @@ files:
217
205
  - ".rspec"
218
206
  - ".ruby-style.yml"
219
207
  - ".travis.yml"
208
+ - CHANGELOG.md
220
209
  - Gemfile
221
210
  - LICENSE.txt
222
211
  - README.md
223
212
  - Rakefile
224
213
  - gemfiles/rails3.gemfile
225
214
  - gemfiles/rails4.gemfile
215
+ - gemfiles/rails5.gemfile
226
216
  - lib/rails_core_extensions.rb
227
217
  - lib/rails_core_extensions/action_controller_sortable.rb
228
218
  - lib/rails_core_extensions/action_view_currency_extensions.rb
@@ -243,11 +233,13 @@ files:
243
233
  - lib/rails_core_extensions/sortable.rb
244
234
  - lib/rails_core_extensions/tasks/position_initializer.rake
245
235
  - lib/rails_core_extensions/time_with_zone.rb
236
+ - lib/rails_core_extensions/transfer_records.rb
246
237
  - lib/rails_core_extensions/version.rb
247
238
  - rails_core_extensions.gemspec
248
239
  - spec/action_controller_sortable_spec.rb
249
240
  - spec/action_view_extensions_spec.rb
250
241
  - spec/active_model_extensions_spec.rb
242
+ - spec/active_record_cloning_spec.rb
251
243
  - spec/active_record_extensions_spec.rb
252
244
  - spec/breadcrumb_spec.rb
253
245
  - spec/concurrency_spec.rb
@@ -256,6 +248,7 @@ files:
256
248
  - spec/spec_helper.rb
257
249
  - spec/spec_helper_model_base.rb
258
250
  - spec/support/coverage_loader.rb
251
+ - spec/transfer_records_spec.rb
259
252
  homepage: http://github.com/sealink/rails_core_extensions
260
253
  licenses:
261
254
  - MIT
@@ -284,6 +277,7 @@ test_files:
284
277
  - spec/action_controller_sortable_spec.rb
285
278
  - spec/action_view_extensions_spec.rb
286
279
  - spec/active_model_extensions_spec.rb
280
+ - spec/active_record_cloning_spec.rb
287
281
  - spec/active_record_extensions_spec.rb
288
282
  - spec/breadcrumb_spec.rb
289
283
  - spec/concurrency_spec.rb
@@ -292,3 +286,4 @@ test_files:
292
286
  - spec/spec_helper.rb
293
287
  - spec/spec_helper_model_base.rb
294
288
  - spec/support/coverage_loader.rb
289
+ - spec/transfer_records_spec.rb