columns_on_demand 4.3.0 → 6.0.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
- SHA1:
3
- metadata.gz: 8ea8794dded2d78daf705ceaab6df85b8a150fcb
4
- data.tar.gz: 0549493f7b65d99480413e6a24d5016d76984251
2
+ SHA256:
3
+ metadata.gz: 1883a4021dfc69d3c3ce1b12c02f14cfb8d5ad40b7dcf0e382c638ebe20528f1
4
+ data.tar.gz: b9da84f7409d34203123dc0c9a2c9ed59ed65004cfb08994ad4f13be1e1bad83
5
5
  SHA512:
6
- metadata.gz: 7f984d613b9eeccb2d14fab83e1dd6948a970d3b482876e6095a6605674bf80b8878afd4ec19b8206a4c830341e3b05ac52a7fb30d40f08ff7edfb8198e630da
7
- data.tar.gz: ae1a56951d46b3703d3156d2275a099a0de958139c6b978c5805064ce28f7b2ddb361458b6462388346cf580de233bfbc95d9f1228694bd5989e40095a80f70f
6
+ metadata.gz: 25931accb7f33e305383400d6d780d119508298a3ae4baa66fdc374daaf459f47cee7fd7390de790af785075ef7a62b53bd6d79716269487e989952d6979a4c2
7
+ data.tar.gz: 5477645b767cbc9bf7f9acff349b6fd7c515980905921137f49f8e335c4ed937b89b2cd689f802fd5b296b5129ae1e73899303dd438265af22ca06e36335a3c7
@@ -0,0 +1,14 @@
1
+ ---
2
+ sudo: false
3
+ language: ruby
4
+ cache: bundler
5
+ dist: bionic
6
+ rvm:
7
+ - 2.6
8
+ services:
9
+ - postgresql
10
+ - mysql
11
+ before_script:
12
+ - createdb -U postgres columns_on_demand_test
13
+ - mysqladmin -u root create columns_on_demand_test
14
+ script: ./test_all.sh
data/Gemfile CHANGED
@@ -1,6 +1,6 @@
1
1
  source "http://rubygems.org"
2
2
 
3
- # Declare your gem's dependencies in transaction_isolation_level.gemspec.
3
+ # Declare your gem's dependencies in columns_on_demand.gemspec.
4
4
  # Bundler will treat runtime dependencies like base dependencies, and
5
5
  # development dependencies will be added by default to the :development group.
6
6
  gemspec
@@ -11,4 +11,4 @@ gemspec
11
11
  # your gem to rubygems.org.
12
12
 
13
13
  gem 'rails', ENV['RAILS_VERSION']
14
- gem 'nokogiri', '~> 1.6.7.2'
14
+ gem 'sqlite3', ENV['SQLITE3_VERSION']
@@ -1,4 +1,4 @@
1
- Copyright (c) 2008-2009 Will Bryant, Sekuda Ltd
1
+ Copyright (c) 2008-2018 Will Bryant, Sekuda Ltd
2
2
 
3
3
  Permission is hereby granted, free of charge, to any person obtaining
4
4
  a copy of this software and associated documentation files (the
data/README.md CHANGED
@@ -21,10 +21,7 @@ Compatibility
21
21
 
22
22
  Supports mysql, mysql2, postgresql, and sqlite3.
23
23
 
24
- Currently tested against Rails 4.2.3, 4.1.12, 4.0.13, 3.2.18, on Ruby 2.1.5.
25
-
26
- Was also previously tested compatible with 2.3.14, 3.0.17, and 3.1.8 on Ruby 2.0.0
27
- or 1.8.7 as appropriate, and may still work for them.
24
+ Currently tested against Rails 6.1.0.rc1, 6.0.3.4, 5.2.4.4, 5.1.7, and 5.0.7.2, with older gem versions compatible with earlier Rails versions.
28
25
 
29
26
 
30
27
  Example
@@ -53,5 +50,7 @@ Thanks
53
50
 
54
51
  * Tim Connor (@tlconnor)
55
52
  * Tobias Matthies (@tobmatth)
53
+ * Phil Ross (@philr)
54
+ * Jens Schmidt (@w3dot0)
56
55
 
57
- Copyright (c) 2008-2015 Will Bryant, Sekuda Ltd, released under the MIT license
56
+ Copyright (c) 2008-2020 Will Bryant, Sekuda Ltd, released under the MIT license
@@ -19,16 +19,7 @@ pages since they are not stored wholly in the record's page itself.
19
19
 
20
20
  Although this plugin is mainly used for BLOB and TEXT columns, it will actually
21
21
  work on all types - and is just as useful for large string fields etc.
22
-
23
-
24
- Compatibility
25
- =============
26
-
27
- Supports mysql, mysql2, postgresql, and sqlite3.
28
-
29
- Currently tested against Rails 3.2.18, 4.0.8, and 4.1.4, on Ruby 2.0.0.
30
22
  EOF
31
- gem.has_rdoc = false
32
23
  gem.author = "Will Bryant"
33
24
  gem.email = "will.bryant@gmail.com"
34
25
  gem.homepage = "http://github.com/willbryant/columns_on_demand"
@@ -41,8 +32,8 @@ EOF
41
32
 
42
33
  gem.add_dependency "activerecord"
43
34
  gem.add_development_dependency "rake"
44
- gem.add_development_dependency "mysql"
45
35
  gem.add_development_dependency "mysql2"
46
36
  gem.add_development_dependency "pg"
47
37
  gem.add_development_dependency "sqlite3"
38
+ gem.add_development_dependency "byebug"
48
39
  end
@@ -5,43 +5,18 @@ module ColumnsOnDemand
5
5
  self.columns_to_load_on_demand = columns_to_load_on_demand.empty? ? blob_and_text_columns : columns_to_load_on_demand.collect(&:to_s)
6
6
 
7
7
  extend ClassMethods
8
- include InstanceMethods
8
+ prepend InstanceMethods
9
9
 
10
10
  class <<self
11
- unless ActiveRecord::VERSION::MAJOR > 3 ||
12
- (ActiveRecord.const_defined?(:AttributeMethods) &&
13
- ActiveRecord::AttributeMethods::const_defined?(:Serialization) &&
14
- ActiveRecord::AttributeMethods::Serialization::const_defined?(:Attribute))
15
- alias_method_chain :define_read_method_for_serialized_attribute, :columns_on_demand
16
- end
17
- alias_method_chain :reset_column_information, :columns_on_demand
18
- end
19
- alias_method_chain :attributes, :columns_on_demand
20
- alias_method_chain :attribute_names, :columns_on_demand
21
- alias_method_chain :read_attribute, :columns_on_demand
22
- alias_method_chain :read_attribute_before_type_cast, :columns_on_demand
23
- if ActiveRecord::AttributeMethods::Read.instance_methods.include?(:_read_attribute)
24
- alias_method_chain :_read_attribute, :columns_on_demand
25
- end
26
- alias_method_chain :missing_attribute, :columns_on_demand
27
- alias_method_chain :reload, :columns_on_demand
28
- if ActiveRecord::AttributeMethods::Dirty.instance_methods.include?(:attribute_changed_in_place?)
29
- alias_method_chain :attribute_changed_in_place?, :columns_on_demand
30
- elsif ActiveRecord::AttributeMethods::Dirty.instance_methods.include?(:changed_attributes)
31
- alias_method_chain :changed_in_place?, :columns_on_demand
11
+ alias reset_column_information_without_columns_on_demand reset_column_information
12
+ alias reset_column_information reset_column_information_with_columns_on_demand
32
13
  end
33
14
  end
34
15
 
35
16
  def reset_column_information_with_columns_on_demand
36
- @columns_to_select = nil
17
+ @columns_to_select = @columns_to_load_by_default = nil
37
18
  reset_column_information_without_columns_on_demand
38
19
  end
39
-
40
- def define_read_method_for_serialized_attribute_with_columns_on_demand(attr_name)
41
- define_read_method_for_serialized_attribute_without_columns_on_demand(attr_name)
42
- scope = method_defined?(:generated_attribute_methods) ? generated_attribute_methods : self
43
- scope.module_eval("def #{attr_name}_with_columns_on_demand; ensure_loaded('#{attr_name}'); #{attr_name}_without_columns_on_demand; end; alias_method_chain :#{attr_name}, :columns_on_demand", __FILE__, __LINE__)
44
- end
45
20
 
46
21
  def blob_and_text_columns
47
22
  columns.inject([]) do |blob_and_text_columns, column|
@@ -54,13 +29,17 @@ module ColumnsOnDemand
54
29
  module ClassMethods
55
30
  # this is the method API as called by ActiveRecord 2.x. we also call it ourselves above in our ActiveRecord 3 extensions.
56
31
  def default_select(qualified)
57
- @columns_to_select ||= (columns.collect(&:name) - columns_to_load_on_demand).collect {|attr_name| connection.quote_column_name(attr_name)}
32
+ @columns_to_select ||= columns_to_load_by_default.collect {|attr_name| connection.quote_column_name(attr_name)}
58
33
  if qualified
59
34
  quoted_table_name + '.' + @columns_to_select.join(", #{quoted_table_name}.")
60
35
  else
61
36
  @columns_to_select.join(", ")
62
37
  end
63
38
  end
39
+
40
+ def columns_to_load_by_default
41
+ @columns_to_load_by_default ||= Set.new(columns.collect(&:name) - columns_to_load_on_demand)
42
+ end
64
43
  end
65
44
 
66
45
  module InstanceMethods
@@ -72,13 +51,17 @@ module ColumnsOnDemand
72
51
  !columns_to_load_on_demand.include?(attr_name) || @attributes.key?(attr_name) || new_record? || columns_loaded.include?(attr_name)
73
52
  end
74
53
 
75
- def attributes_with_columns_on_demand
76
- load_attributes(*columns_to_load_on_demand.reject {|attr_name| column_loaded?(attr_name)})
77
- attributes_without_columns_on_demand
54
+ def attributes
55
+ loaded_attributes = @attributes.keys
56
+ if loaded_attributes.size == self.class.columns_to_load_by_default.size &&
57
+ loaded_attributes.size == (self.class.columns_to_load_by_default & loaded_attributes).size
58
+ load_attributes(*columns_to_load_on_demand.reject {|attr_name| column_loaded?(attr_name)})
59
+ end
60
+ super
78
61
  end
79
62
 
80
- def attribute_names_with_columns_on_demand
81
- (attribute_names_without_columns_on_demand + columns_to_load_on_demand).uniq.sort
63
+ def attribute_names
64
+ (super + columns_to_load_on_demand).uniq.sort
82
65
  end
83
66
 
84
67
  def load_attributes(*attr_names)
@@ -87,42 +70,13 @@ module ColumnsOnDemand
87
70
  values = self.class.connection.select_rows(
88
71
  "SELECT #{attr_names.collect {|attr_name| self.class.connection.quote_column_name(attr_name)}.join(", ")}" +
89
72
  " FROM #{self.class.quoted_table_name}" +
90
- " WHERE #{self.class.connection.quote_column_name(self.class.primary_key)} = #{self.class.quote_value(id, self.class.columns_hash[self.class.primary_key])}")
73
+ " WHERE #{self.class.connection.quote_column_name(self.class.primary_key)} = #{self.class.connection.quote(id)}")
91
74
  row = values.first || raise(ActiveRecord::RecordNotFound, "Couldn't find #{self.class.name} with ID=#{id}")
92
75
 
93
76
  attr_names.each_with_index do |attr_name, i|
94
77
  columns_loaded << attr_name
95
78
  value = row[i]
96
-
97
- if @attributes.respond_to?(:write_from_database)
98
- # activerecord 4.2 or later, which make it easy to replicate the normal typecasting and deserialization logic
99
- @attributes.write_from_database(attr_name, value)
100
-
101
- elsif coder = self.class.serialized_attributes[attr_name]
102
- # activerecord 4.1 or earlier, with a serialized column
103
- # for some database adapters, @column_types_override gets populated with type data from query used to load the record originally.
104
- # this is fine, but unfortunately some special-case "decorate_columns" code in ActiveRecord will wrap those types in serialization
105
- # objects, and it does this for each column listed in @serialized_column_names *even if they are not present in the query results*.
106
- # as a result it unfortunately overrides the normal @column_type with a @column_type_override with a nil @column, which explodes
107
- # when it tries to run the typecast. make it use the normal @column_type value, since we know that we've loading the regular column.
108
- @column_types_override.delete(attr_name) if @column_types_override
109
-
110
- if ActiveRecord.const_defined?(:AttributeMethods) &&
111
- ActiveRecord::AttributeMethods::const_defined?(:Serialization) &&
112
- ActiveRecord::AttributeMethods::Serialization::const_defined?(:Attribute)
113
- # in 3.2 @attributes has a special Attribute struct to help cache both serialized and unserialized forms
114
- @attributes[attr_name] = ActiveRecord::AttributeMethods::Serialization::Attribute.new(coder, value, :serialized)
115
- elsif ActiveRecord::VERSION::MAJOR == 3 && ActiveRecord::VERSION::MINOR == 1
116
- # from 3.1 it has the deserialized form
117
- @attributes[attr_name] = coder.load value
118
- else
119
- # in 2.3 an 3.0, @attributes has the serialized form
120
- @attributes[attr_name] = value
121
- end
122
- else
123
- # activerecord 4.1 or earlier, with a regular unserialized column
124
- @attributes[attr_name] = value
125
- end
79
+ @attributes.write_from_database(attr_name, value)
126
80
  end
127
81
  end
128
82
 
@@ -130,39 +84,49 @@ module ColumnsOnDemand
130
84
  load_attributes(attr_name.to_s) unless column_loaded?(attr_name.to_s)
131
85
  end
132
86
 
133
- def changed_in_place_with_columns_on_demand?(attr_name)
134
- column_loaded?(attr_name) && changed_in_place_without_columns_on_demand?(attr_name)
87
+ def changed_in_place?(attr_name)
88
+ column_loaded?(attr_name) && super(attr_name)
89
+ end
90
+
91
+ def attribute_changed_in_place?(attr_name)
92
+ column_loaded?(attr_name) && super(attr_name)
93
+ end
94
+
95
+ def read_attribute(attr_name, &block)
96
+ ensure_loaded(attr_name)
97
+ super(attr_name, &block)
135
98
  end
136
99
 
137
- def attribute_changed_in_place_with_columns_on_demand?(attr_name)
138
- column_loaded?(attr_name) && attribute_changed_in_place_without_columns_on_demand?(attr_name)
100
+ def read_attribute_before_type_cast(attr_name)
101
+ ensure_loaded(attr_name)
102
+ super(attr_name)
139
103
  end
140
104
 
141
- def read_attribute_with_columns_on_demand(attr_name, &block)
105
+ def _read_attribute(attr_name, &block)
142
106
  ensure_loaded(attr_name)
143
- read_attribute_without_columns_on_demand(attr_name, &block)
107
+ super(attr_name, &block)
144
108
  end
145
109
 
146
- def read_attribute_before_type_cast_with_columns_on_demand(attr_name)
110
+ def write_attribute(attr_name, value)
147
111
  ensure_loaded(attr_name)
148
- read_attribute_before_type_cast_without_columns_on_demand(attr_name)
112
+ super(attr_name, value)
149
113
  end
150
114
 
151
- def _read_attribute_with_columns_on_demand(attr_name, &block)
115
+ def _write_attribute(attr_name, value)
152
116
  ensure_loaded(attr_name)
153
- _read_attribute_without_columns_on_demand(attr_name, &block)
117
+ super(attr_name, value)
154
118
  end
155
119
 
156
- def missing_attribute_with_columns_on_demand(attr_name, *args)
120
+ def missing_attribute(attr_name, *args)
157
121
  if columns_to_load_on_demand.include?(attr_name)
158
122
  load_attributes(attr_name)
159
123
  else
160
- missing_attribute_without_columns_on_demand(attr_name, *args)
124
+ super(attr_name, *args)
161
125
  end
162
126
  end
163
127
 
164
- def reload_with_columns_on_demand(*args)
165
- reload_without_columns_on_demand(*args).tap do
128
+ def reload(*args)
129
+ super(*args).tap do
166
130
  columns_loaded.clear
167
131
  columns_to_load_on_demand.each do |attr_name|
168
132
  if @attributes.respond_to?(:reset)
@@ -177,37 +141,45 @@ module ColumnsOnDemand
177
141
  end
178
142
  end
179
143
 
180
- module RelationMethodsArity2
181
- def build_select_with_columns_on_demand(arel, selects)
182
- if (selects.empty? || selects == [table[Arel.star]] || selects == ['*']) && klass < ColumnsOnDemand::InstanceMethods
183
- build_select_without_columns_on_demand(arel, [default_select(true)])
184
- else
185
- build_select_without_columns_on_demand(arel, selects)
186
- end
187
- end
188
- end
189
-
190
- module RelationMethodsArity1
191
- def build_select_with_columns_on_demand(arel)
144
+ module RelationMethods
145
+ def build_select(arel)
192
146
  if (select_values.empty? || select_values == [table[Arel.star]] || select_values == ['*']) && klass < ColumnsOnDemand::InstanceMethods
193
147
  arel.project(*arel_columns([default_select(true)]))
194
148
  else
195
- build_select_without_columns_on_demand(arel)
149
+ super(arel)
196
150
  end
197
151
  end
198
152
  end
199
153
  end
200
154
 
201
155
  ActiveRecord::Base.send(:extend, ColumnsOnDemand::BaseMethods)
202
-
203
- if ActiveRecord.const_defined?(:Relation)
204
- if ActiveRecord::Relation.instance_method(:build_select).arity == 1
205
- # 4.2.1 and above
206
- ActiveRecord::Relation.send(:include, ColumnsOnDemand::RelationMethodsArity1)
207
- else
208
- # 4.2.0 and below
209
- ActiveRecord::Relation.send(:include, ColumnsOnDemand::RelationMethodsArity2)
156
+ ActiveRecord::Relation.send(:prepend, ColumnsOnDemand::RelationMethods)
157
+
158
+ # work around ActiveRecord 5.0 and 5.1 converting uninitialized attributes to value nil on save
159
+ # (due to dirty.rb mapping @attributes). this is not only a problem for columns_on_demand as it
160
+ # means that a MissingAttributeError will never be raised after save, but we suffer more.
161
+ # ActiveRecord 4.2's Attribute doesn't have forgetting_assignment (or this problem).
162
+ if ActiveRecord.const_defined?(:Attribute) && ActiveRecord::Attribute.uninitialized(nil, nil).try(:forgetting_assignment).try(:initialized?)
163
+ module ActiveRecord
164
+ class Attribute # :nodoc:
165
+ class Uninitialized < Attribute # :nodoc:
166
+ def forgetting_assignment
167
+ dup
168
+ end
169
+ end
170
+ end
210
171
  end
172
+ end
211
173
 
212
- ActiveRecord::Relation.alias_method_chain :build_select, :columns_on_demand
174
+ # same for 5.2
175
+ if ActiveModel.const_defined?(:Attribute) && ActiveModel::Attribute.uninitialized(nil, nil).try(:forgetting_assignment).try(:initialized?)
176
+ module ActiveModel
177
+ class Attribute # :nodoc:
178
+ class Uninitialized < Attribute # :nodoc:
179
+ def forgetting_assignment
180
+ dup
181
+ end
182
+ end
183
+ end
184
+ end
213
185
  end
@@ -1,3 +1,3 @@
1
1
  module ColumnsOnDemand
2
- VERSION = '4.3.0'
2
+ VERSION = '6.0.0'
3
3
  end
@@ -43,7 +43,11 @@ class ColumnsOnDemandTest < ActiveSupport::TestCase
43
43
  end
44
44
 
45
45
  fixtures :all
46
- self.use_transactional_fixtures = true
46
+ if respond_to?(:use_transactional_tests=)
47
+ self.use_transactional_tests = true
48
+ else
49
+ self.use_transactional_fixtures = true
50
+ end
47
51
 
48
52
  test "it lists explicitly given columns for loading on demand" do
49
53
  assert_equal ["file_data", "processing_log", "original_filename"], Explicit.columns_to_load_on_demand
@@ -54,11 +58,11 @@ class ColumnsOnDemandTest < ActiveSupport::TestCase
54
58
  end
55
59
 
56
60
  test "it selects all the other columns for loading eagerly" do
57
- assert_match /\W*id\W*, \W*results\W*, \W*processed_at\W*/, Explicit.default_select(false)
58
- assert_match /\W*explicits\W*.results/, Explicit.default_select(true)
61
+ assert_match(/\W*id\W*, \W*results\W*, \W*processed_at\W*/, Explicit.default_select(false))
62
+ assert_match(/\W*explicits\W*.results/, Explicit.default_select(true))
59
63
 
60
- assert_match /\W*id\W*, \W*original_filename\W*, \W*processed_at\W*/, Implicit.default_select(false)
61
- assert_match /\W*implicits\W*.original_filename/, Implicit.default_select(true)
64
+ assert_match(/\W*id\W*, \W*original_filename\W*, \W*processed_at\W*/, Implicit.default_select(false))
65
+ assert_match(/\W*implicits\W*.original_filename/, Implicit.default_select(true))
62
66
  end
63
67
 
64
68
  test "it doesn't load the columns_to_load_on_demand straight away when finding the records" do
@@ -92,10 +96,10 @@ class ColumnsOnDemandTest < ActiveSupport::TestCase
92
96
 
93
97
  record = Implicit.first
94
98
  assert_not_loaded record, "file_data"
95
- assert_equal nil, record.file_data
99
+ assert_nil record.file_data
96
100
  assert_loaded record, "file_data"
97
101
  assert_no_queries do
98
- assert_equal nil, record.file_data
102
+ assert_nil record.file_data
99
103
  end
100
104
  end
101
105
 
@@ -132,6 +136,25 @@ class ColumnsOnDemandTest < ActiveSupport::TestCase
132
136
  assert !attributes["processing_log"].blank?
133
137
  end
134
138
  end
139
+
140
+ test "it doesn't load the column when generating #attributes if not included in the select() list" do
141
+ attributes = Implicit.select("id, original_filename").first.attributes
142
+ assert_equal "somefile.txt", attributes["original_filename"]
143
+ assert !attributes.has_key?("file_data")
144
+ end
145
+
146
+ test "it loads the column when generating #attributes if included in the select() list" do
147
+ attributes = Implicit.select("id, original_filename, file_data").first.attributes
148
+ assert_equal "somefile.txt", attributes["original_filename"]
149
+ assert_equal "This is the file data!", attributes["file_data"]
150
+ end
151
+
152
+ test "it loads the column when changing its value" do
153
+ record = Implicit.first
154
+ record.file_data = 'This is the new file data!'
155
+ assert_equal "This is the file data!", record.file_data_was
156
+ assert_equal ["This is the file data!", "This is the new file data!"], record.changes[:file_data]
157
+ end
135
158
 
136
159
  test "it loads the column when generating #to_json" do
137
160
  ActiveRecord::Base.include_root_in_json = true
@@ -156,8 +179,31 @@ class ColumnsOnDemandTest < ActiveSupport::TestCase
156
179
 
157
180
  assert_not_loaded record, "file_data"
158
181
  assert_equal "New file data", record.file_data
182
+ assert_not_equal old_object_id, record.file_data.object_id
159
183
  end
160
184
 
185
+ test "it does not think the column has been loaded if a reloaded instance that has not loaded the attribute is saved" do
186
+ record = Implicit.first
187
+ record.file_data = "New file data"
188
+ record.save!
189
+
190
+ record.reload
191
+ record.save!
192
+
193
+ assert_equal "New file data", record.file_data
194
+ end
195
+
196
+ test "it does not think the column has been loaded if a fresh instance that has not loaded the attribute is saved" do
197
+ record = Implicit.first
198
+ record.file_data = "New file data"
199
+ record.save!
200
+
201
+ record = Implicit.find(record.id)
202
+ record.save!
203
+
204
+ assert_equal "New file data", record.file_data
205
+ end
206
+
161
207
  test "it doesn't override custom select() finds" do
162
208
  record = Implicit.select("id, file_data").first
163
209
  klass = ActiveRecord.const_defined?(:MissingAttributeError) ? ActiveRecord::MissingAttributeError : ActiveModel::MissingAttributeError
@@ -194,42 +240,7 @@ class ColumnsOnDemandTest < ActiveSupport::TestCase
194
240
  assert_equal "This is the file data!", record.file_data # check it doesn't raise
195
241
  end
196
242
 
197
- test "it updates the select strings when columns are changed and the column information is reset" do
198
- ActiveRecord::Schema.define(:version => 1) do
199
- create_table :dummies, :force => true do |t|
200
- t.string :some_field
201
- t.binary :big_field
202
- end
203
- end
204
-
205
- class Dummy < ActiveRecord::Base
206
- columns_on_demand
207
- end
208
-
209
- assert_match /\W*id\W*, \W*some_field\W*/, Dummy.default_select(false)
210
-
211
- ActiveRecord::Schema.define(:version => 2) do
212
- create_table :dummies, :force => true do |t|
213
- t.string :some_field
214
- t.binary :big_field
215
- t.string :another_field
216
- end
217
- end
218
-
219
- assert_match /\W*id\W*, \W*some_field\W*/, Dummy.default_select(false)
220
- Dummy.reset_column_information
221
- assert_match /\W*id\W*, \W*some_field\W*, \W*another_field\W*/, Dummy.default_select(false)
222
- end
223
-
224
243
  test "it handles STI models" do
225
- ActiveRecord::Schema.define(:version => 1) do
226
- create_table :stis, :force => true do |t|
227
- t.string :type
228
- t.string :some_field
229
- t.binary :big_field
230
- end
231
- end
232
-
233
244
  class Sti < ActiveRecord::Base
234
245
  columns_on_demand
235
246
  end
@@ -238,8 +249,8 @@ class ColumnsOnDemandTest < ActiveSupport::TestCase
238
249
  columns_on_demand :some_field
239
250
  end
240
251
 
241
- assert_match /\W*id\W*, \W*type\W*, \W*some_field\W*/, Sti.default_select(false)
242
- assert_match /\W*id\W*, \W*type\W*, \W*big_field\W*/, StiChild.default_select(false)
252
+ assert_match(/\W*id\W*, \W*type\W*, \W*some_field\W*/, Sti.default_select(false))
253
+ assert_match(/\W*id\W*, \W*type\W*, \W*big_field\W*/, StiChild.default_select(false))
243
254
  end
244
255
 
245
256
  test "it works on child records loaded from associations" do
@@ -279,9 +290,9 @@ class ColumnsOnDemandTest < ActiveSupport::TestCase
279
290
 
280
291
  assert !ValidatedImplicit.new(:original_filename => "test.txt").valid?
281
292
  instance = ValidatedImplicit.create!(:original_filename => "test.txt", :file_data => "test file data", :results => "test results")
282
- instance.update_attributes!({}) # file_data and results are already loaded
293
+ assert instance.valid? # file_data and results are already loaded
283
294
  new_instance = ValidatedImplicit.find(instance.id)
284
- new_instance.update_attributes!({}) # file_data and results aren't loaded yet, but will be loaded to validate
295
+ assert new_instance.valid? # file_data and results aren't loaded yet, but will be loaded to validate
285
296
  end
286
297
 
287
298
  test "it works with serialized columns" do
@@ -322,3 +333,38 @@ class ColumnsOnDemandTest < ActiveSupport::TestCase
322
333
  assert_equal select_sql, reference_sql
323
334
  end
324
335
  end
336
+
337
+ class ColumnsOnDemandSchemaTest < ActiveSupport::TestCase
338
+ if respond_to?(:use_transactional_tests=)
339
+ self.use_transactional_tests = false
340
+ else
341
+ self.use_transactional_fixtures = false
342
+ end
343
+
344
+ test "it updates the select strings when columns are changed and the column information is reset" do
345
+ ActiveRecord::Schema.define(:version => 1) do
346
+ create_table :dummies, :force => true do |t|
347
+ t.string :some_field
348
+ t.binary :big_field
349
+ end
350
+ end
351
+
352
+ class Dummy < ActiveRecord::Base
353
+ columns_on_demand
354
+ end
355
+
356
+ assert_match(/\W*id\W*, \W*some_field\W*/, Dummy.default_select(false))
357
+
358
+ ActiveRecord::Schema.define(:version => 2) do
359
+ create_table :dummies, :force => true do |t|
360
+ t.string :some_field
361
+ t.binary :big_field
362
+ t.string :another_field
363
+ end
364
+ end
365
+
366
+ assert_match(/\W*id\W*, \W*some_field\W*/, Dummy.default_select(false))
367
+ Dummy.reset_column_information
368
+ assert_match(/\W*id\W*, \W*some_field\W*, \W*another_field\W*/, Dummy.default_select(false))
369
+ end
370
+ end
@@ -27,4 +27,10 @@ ActiveRecord::Schema.define(:version => 0) do
27
27
  create_table :serializings, :force => true do |t|
28
28
  t.binary :data
29
29
  end
30
+
31
+ create_table :stis, :force => true do |t|
32
+ t.string :type
33
+ t.string :some_field
34
+ t.binary :big_field
35
+ end
30
36
  end
@@ -0,0 +1,19 @@
1
+ #!/bin/sh
2
+
3
+ set -e
4
+
5
+ for version in 5.0.7.2 5.1.7 5.2.4.4
6
+ do
7
+ RAILS_VERSION=$version SQLITE3_VERSION=1.3.9 bundle update rails sqlite3
8
+ RAILS_ENV=sqlite3 bundle exec rake
9
+ RAILS_ENV=postgresql bundle exec rake
10
+ RAILS_ENV=mysql2 bundle exec rake
11
+ done
12
+
13
+ for version in 6.0.3.4 6.1.0.rc1
14
+ do
15
+ RAILS_VERSION=$version SQLITE3_VERSION=1.4.1 bundle update rails sqlite3
16
+ RAILS_ENV=sqlite3 bundle exec rake
17
+ RAILS_ENV=postgresql bundle exec rake
18
+ RAILS_ENV=mysql2 bundle exec rake
19
+ done
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: columns_on_demand
3
3
  version: !ruby/object:Gem::Version
4
- version: 4.3.0
4
+ version: 6.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Will Bryant
8
- autorequire:
8
+ autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-06-07 00:00:00.000000000 Z
11
+ date: 2020-11-12 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activerecord
@@ -39,7 +39,7 @@ dependencies:
39
39
  - !ruby/object:Gem::Version
40
40
  version: '0'
41
41
  - !ruby/object:Gem::Dependency
42
- name: mysql
42
+ name: mysql2
43
43
  requirement: !ruby/object:Gem::Requirement
44
44
  requirements:
45
45
  - - ">="
@@ -53,7 +53,7 @@ dependencies:
53
53
  - !ruby/object:Gem::Version
54
54
  version: '0'
55
55
  - !ruby/object:Gem::Dependency
56
- name: mysql2
56
+ name: pg
57
57
  requirement: !ruby/object:Gem::Requirement
58
58
  requirements:
59
59
  - - ">="
@@ -67,7 +67,7 @@ dependencies:
67
67
  - !ruby/object:Gem::Version
68
68
  version: '0'
69
69
  - !ruby/object:Gem::Dependency
70
- name: pg
70
+ name: sqlite3
71
71
  requirement: !ruby/object:Gem::Requirement
72
72
  requirements:
73
73
  - - ">="
@@ -81,7 +81,7 @@ dependencies:
81
81
  - !ruby/object:Gem::Version
82
82
  version: '0'
83
83
  - !ruby/object:Gem::Dependency
84
- name: sqlite3
84
+ name: byebug
85
85
  requirement: !ruby/object:Gem::Requirement
86
86
  requirements:
87
87
  - - ">="
@@ -108,20 +108,13 @@ description: |
108
108
 
109
109
  Although this plugin is mainly used for BLOB and TEXT columns, it will actually
110
110
  work on all types - and is just as useful for large string fields etc.
111
-
112
-
113
- Compatibility
114
- =============
115
-
116
- Supports mysql, mysql2, postgresql, and sqlite3.
117
-
118
- Currently tested against Rails 3.2.18, 4.0.8, and 4.1.4, on Ruby 2.0.0.
119
111
  email: will.bryant@gmail.com
120
112
  executables: []
121
113
  extensions: []
122
114
  extra_rdoc_files: []
123
115
  files:
124
116
  - ".gitignore"
117
+ - ".travis.yml"
125
118
  - Gemfile
126
119
  - MIT-LICENSE
127
120
  - README.md
@@ -138,11 +131,12 @@ files:
138
131
  - test/fixtures/parents.yml
139
132
  - test/schema.rb
140
133
  - test/test_helper.rb
134
+ - test_all.sh
141
135
  homepage: http://github.com/willbryant/columns_on_demand
142
136
  licenses:
143
137
  - MIT
144
138
  metadata: {}
145
- post_install_message:
139
+ post_install_message:
146
140
  rdoc_options: []
147
141
  require_paths:
148
142
  - lib
@@ -157,9 +151,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
157
151
  - !ruby/object:Gem::Version
158
152
  version: '0'
159
153
  requirements: []
160
- rubyforge_project:
161
- rubygems_version: 2.2.5
162
- signing_key:
154
+ rubygems_version: 3.0.3
155
+ signing_key:
163
156
  specification_version: 4
164
157
  summary: Lazily loads large columns on demand.
165
158
  test_files: