torque-postgresql 2.1.0 → 2.2.0

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.
Files changed (33) hide show
  1. checksums.yaml +4 -4
  2. data/lib/torque/postgresql/adapter/database_statements.rb +3 -15
  3. data/lib/torque/postgresql/adapter/quoting.rb +1 -1
  4. data/lib/torque/postgresql/adapter/schema_dumper.rb +2 -2
  5. data/lib/torque/postgresql/adapter/schema_statements.rb +5 -1
  6. data/lib/torque/postgresql/adapter.rb +20 -4
  7. data/lib/torque/postgresql/associations/belongs_to_many_association.rb +8 -6
  8. data/lib/torque/postgresql/associations/preloader/association.rb +2 -2
  9. data/lib/torque/postgresql/attributes/builder/enum.rb +5 -5
  10. data/lib/torque/postgresql/attributes/builder/period.rb +2 -6
  11. data/lib/torque/postgresql/attributes/enum.rb +1 -1
  12. data/lib/torque/postgresql/attributes/enum_set.rb +1 -1
  13. data/lib/torque/postgresql/base.rb +1 -1
  14. data/lib/torque/postgresql/config.rb +6 -0
  15. data/lib/torque/postgresql/inheritance.rb +1 -1
  16. data/lib/torque/postgresql/reflection/belongs_to_many_reflection.rb +4 -2
  17. data/lib/torque/postgresql/relation/inheritance.rb +9 -14
  18. data/lib/torque/postgresql/version.rb +1 -1
  19. data/lib/torque/postgresql.rb +0 -1
  20. data/lib/torque/range.rb +0 -2
  21. data/spec/factories/item.rb +5 -0
  22. data/spec/models/item.rb +3 -0
  23. data/spec/models/question.rb +3 -0
  24. data/spec/models/question_select.rb +2 -0
  25. data/spec/schema.rb +19 -1
  26. data/spec/tests/arel_spec.rb +30 -0
  27. data/spec/tests/belongs_to_many_spec.rb +31 -10
  28. data/spec/tests/period_spec.rb +9 -0
  29. data/spec/tests/range_spec.rb +1 -1
  30. data/spec/tests/table_inheritance_spec.rb +30 -21
  31. metadata +37 -32
  32. data/lib/torque/postgresql/coder.rb +0 -133
  33. data/spec/tests/coder_spec.rb +0 -367
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: cd2096d27cb0b11fd4cd2048627bf0b12dcd905d4240ea0251366f580a0afcf2
4
- data.tar.gz: c6d948dd77768feff3d85284bc838b8fb03c91233cc33ecdc8b3c22e463038c3
3
+ metadata.gz: cb3d81538edfb988d8566295fac7d055208e399d552b619d9d8b3b9234254686
4
+ data.tar.gz: 7c7c62bec966085eccbdc351041a94d04788e40f84b1120d88c1673c9d0e3b3c
5
5
  SHA512:
6
- metadata.gz: 3f61ba4bf68f2519090bb23b259cf9d8fa2c59f5a9935c867fe0dd2629eeeddd21e7a9f68a0e168550f696564d9613a4617ed6619ac4fe1f3d7660bf3fd1fc9c
7
- data.tar.gz: dbb298a6df589aa9368fb70f933b5ece9984bfc3661d667c7e42b989e2bdda6159aafbf78a303f9926f3b17dbc762473454f4646e91e976a21a0fd439a57c9f9
6
+ metadata.gz: 93cf49b971a0013d3f10263917437b7a552632e62f462d43b91aaad86ec66ba10b20a014bf2bbcaa883f1c6801df423fd3d98dd8d9546bd849920bb98b743e6c
7
+ data.tar.gz: 88cf63c02e13e80e48b5dfbe66e9157a52ecc8cc11410f0688e97a6c28e7f25a03adc9c7b71a45ffe9384a81debbf1a29d55363145a4ae6568c82cc9f7207a30
@@ -42,6 +42,8 @@ module Torque
42
42
  m.register_type 'interval', OID::Interval.new
43
43
  m.register_type 'line', OID::Line.new
44
44
  m.register_type 'segment', OID::Segment.new
45
+
46
+ m.alias_type 'regclass', 'varchar'
45
47
  end
46
48
 
47
49
  # :nodoc:
@@ -123,7 +125,7 @@ module Torque
123
125
  SQL
124
126
 
125
127
  tables.map do |(table, refs)|
126
- [table, Coder.decode(refs)]
128
+ [table, PG::TextDecoder::Array.new.decode(refs)]
127
129
  end.to_h
128
130
  end
129
131
 
@@ -147,20 +149,6 @@ module Torque
147
149
  SQL
148
150
  end
149
151
 
150
- # Extracts the value from a PostgreSQL column default definition.
151
- def extract_value_from_default(default)
152
- case default
153
- # Array elements
154
- when /\AARRAY\[(.*)\]\z/
155
- # TODO: Improve this since it's not the most safe approach
156
- eval(default.gsub(/ARRAY|::\w+(\[\])?/, ''))
157
- else
158
- super
159
- end
160
- rescue SyntaxError
161
- # If somethin goes wrong with the eval, just return nil
162
- end
163
-
164
152
  end
165
153
  end
166
154
  end
@@ -20,7 +20,7 @@ module Torque
20
20
  end
21
21
 
22
22
  def quote_default_expression(value, column)
23
- if value.class <= Array
23
+ if column.dig(:options, :array) && value.class <= Array
24
24
  quote(value) + '::' + column.sql_type
25
25
  else
26
26
  super
@@ -43,13 +43,13 @@ module Torque
43
43
  inherited_tables = @connection.inherited_tables
44
44
  sorted_tables = @connection.tables.sort - @connection.views
45
45
 
46
- stream.puts " # These are the common tables managed"
46
+ stream.puts " # These are the common tables"
47
47
  (sorted_tables - inherited_tables.keys).each do |table_name|
48
48
  table(table_name, stream) unless ignored?(table_name)
49
49
  end
50
50
 
51
51
  if inherited_tables.present?
52
- stream.puts " # These are tables that has inheritance"
52
+ stream.puts " # These are tables that have inheritance"
53
53
  inherited_tables.each do |table_name, inherits|
54
54
  next if ignored?(table_name)
55
55
 
@@ -70,7 +70,11 @@ module Torque
70
70
 
71
71
  # Returns all values that an enum type can have.
72
72
  def enum_values(name)
73
- select_values("SELECT unnest(enum_range(NULL::#{name}))", 'SCHEMA')
73
+ select_values(<<-SQL.squish, 'SCHEMA')
74
+ SELECT enumlabel FROM pg_enum
75
+ WHERE enumtypid = #{quote(name)}::regtype::oid
76
+ ORDER BY enumsortorder
77
+ SQL
74
78
  end
75
79
 
76
80
  # Rewrite the method that creates tables to easily accept extra options
@@ -15,7 +15,14 @@ module Torque
15
15
  include DatabaseStatements
16
16
  include SchemaStatements
17
17
 
18
- INJECT_WHERE_REGEX = /(DO UPDATE SET.*excluded\.[^ ]+) RETURNING/.freeze
18
+ # :nodoc:
19
+ class DeduplicatableArray < ::Array
20
+ def deduplicate
21
+ map { |value| -value }
22
+ end
23
+
24
+ alias :-@ :deduplicate
25
+ end
19
26
 
20
27
  # Get the current PostgreSQL version as a Gem Version.
21
28
  def version
@@ -29,19 +36,28 @@ module Torque
29
36
  super.merge(options.extract!(:inherits))
30
37
  end
31
38
 
32
- # Allow filtered bulk insert by adding the where clause. This method is only used by
33
- # +InsertAll+, so it somewhat safe to override it
39
+ # Allow filtered bulk insert by adding the where clause. This method is
40
+ # only used by +InsertAll+, so it somewhat safe to override it
34
41
  def build_insert_sql(insert)
35
42
  super.tap do |sql|
36
43
  if insert.update_duplicates? && insert.where_condition?
37
44
  if insert.returning
38
- sql.gsub!(INJECT_WHERE_REGEX, "\\1 WHERE #{insert.where} RETURNING")
45
+ sql.sub!(' RETURNING ', " WHERE #{insert.where} RETURNING ")
39
46
  else
40
47
  sql << " WHERE #{insert.where}"
41
48
  end
42
49
  end
43
50
  end
44
51
  end
52
+
53
+ # Extend the extract default value to support array
54
+ def extract_value_from_default(default)
55
+ return super unless Torque::PostgreSQL.config.use_extended_defaults
56
+ return super unless default&.match(/ARRAY\[(.*?)\](?:::"?([\w. ]+)"?(?:\[\])+)?$/)
57
+
58
+ arr = $1.split(/(?!\B\[[^\]]*), ?(?![^\[]*\]\B)/)
59
+ DeduplicatableArray.new(arr.map(&method(:extract_value_from_default)))
60
+ end
45
61
  end
46
62
 
47
63
  ActiveRecord::ConnectionAdapters::PostgreSQLAdapter.prepend Adapter
@@ -60,9 +60,11 @@ module Torque
60
60
  target
61
61
  end
62
62
 
63
- def build_changes
63
+ def build_changes(from_target = false)
64
+ return yield if defined?(@_building_changes) && @_building_changes
65
+
64
66
  @_building_changes = true
65
- yield.tap { ids_writer(ids_reader) }
67
+ yield.tap { ids_writer(from_target ? ids_reader : stale_state) }
66
68
  ensure
67
69
  @_building_changes = nil
68
70
  end
@@ -111,7 +113,7 @@ module Torque
111
113
  end
112
114
 
113
115
  def insert_record(record, *)
114
- super.tap do |saved|
116
+ (record.persisted? || super).tap do |saved|
115
117
  ids_rewriter(record.read_attribute(klass_attr), :<<) if saved
116
118
  end
117
119
  end
@@ -192,15 +194,15 @@ module Torque
192
194
 
193
195
  ## HAS MANY
194
196
  def replace_records(*)
195
- build_changes { super }
197
+ build_changes(true) { super }
196
198
  end
197
199
 
198
200
  def concat_records(*)
199
- build_changes { super }
201
+ build_changes(true) { super }
200
202
  end
201
203
 
202
204
  def delete_or_destroy(*)
203
- build_changes { super }
205
+ build_changes(true) { super }
204
206
  end
205
207
 
206
208
  def difference(a, b)
@@ -41,8 +41,8 @@ module Torque
41
41
  end
42
42
  end
43
43
 
44
- if PostgreSQL::AR610
45
- # This is how Rails 6.1 now load the records
44
+ if PostgreSQL::AR604
45
+ # This is how Rails 6.0.4 and 6.1 now load the records
46
46
  def load_records
47
47
  return super unless connected_through_array?
48
48
 
@@ -33,13 +33,13 @@ module Torque
33
33
  def values_methods
34
34
  return @values_methods if defined?(@values_methods)
35
35
 
36
- prefix = options.fetch(:prefix, nil).try(:<<, '_')
37
- suffix = options.fetch(:suffix, nil).try(:prepend, '_')
36
+ prefix = options.fetch(:prefix, nil)
37
+ suffix = options.fetch(:suffix, nil)
38
38
 
39
- prefix = attribute + '_' if prefix == true
40
- suffix = '_' + attribute if suffix == true
39
+ prefix = attribute if prefix == true
40
+ suffix = attribute if suffix == true
41
41
 
42
- base = "#{prefix}%s#{suffix}"
42
+ base = [prefix, '%s', suffix].compact.join('_')
43
43
 
44
44
  @values_methods = begin
45
45
  values.map do |val|
@@ -452,12 +452,8 @@ module Torque
452
452
  def instance_current_on?
453
453
  attr_value = threshold.present? ? method_names[:real] : attribute
454
454
  default_value = default.inspect
455
- [
456
- "return #{default_value} if #{attr_value}.nil?",
457
- "return #{default_value} if #{attr_value}.min.try(:infinite?)",
458
- "return #{default_value} if #{attr_value}.max.try(:infinite?)",
459
- "#{attr_value}.min < value && #{attr_value}.max > value",
460
- ].join("\n")
455
+
456
+ "#{attr_value}.nil? ? #{default_value} : #{attr_value}.include?(value)"
461
457
  end
462
458
 
463
459
  def instance_start
@@ -29,7 +29,7 @@ module Torque
29
29
  def include_on(klass, method_name = nil)
30
30
  method_name ||= Torque::PostgreSQL.config.enum.base_method
31
31
  Builder.include_on(klass, method_name, Builder::Enum) do |builder|
32
- defined_enums[builder.attribute.to_sym] = builder.subtype
32
+ defined_enums[builder.attribute.to_s] = builder.subtype.klass
33
33
  end
34
34
  end
35
35
 
@@ -32,7 +32,7 @@ module Torque
32
32
  def include_on(klass, method_name = nil)
33
33
  method_name ||= Torque::PostgreSQL.config.enum.set_method
34
34
  Builder.include_on(klass, method_name, Builder::Enum, set_features: true) do |builder|
35
- defined_enums[builder.attribute.to_sym] = builder.subtype
35
+ defined_enums[builder.attribute.to_s] = builder.subtype
36
36
  end
37
37
  end
38
38
 
@@ -40,7 +40,7 @@ module Torque
40
40
 
41
41
  pg_class = ::Arel::Table.new('pg_class')
42
42
  source = ::Arel::Table.new(subclass.table_name, as: 'source')
43
- quoted_id = ::Arel::Nodes::Quoted.new(self.class.connection.quote(id))
43
+ quoted_id = ::Arel::Nodes::Quoted.new(id)
44
44
 
45
45
  query = ::Arel::SelectManager.new(pg_class)
46
46
  query.join(source).on(pg_class['oid'].eq(source['tableoid']))
@@ -5,6 +5,7 @@ module Torque
5
5
  include ActiveSupport::Configurable
6
6
 
7
7
  # Stores a version check for compatibility purposes
8
+ AR604 = (ActiveRecord.gem_version >= Gem::Version.new('6.0.4'))
8
9
  AR610 = (ActiveRecord.gem_version >= Gem::Version.new('6.1.0'))
9
10
 
10
11
  # Use the same logger as the Active Record one
@@ -25,6 +26,11 @@ module Torque
25
26
  # same configuration is set to true
26
27
  config.eager_load = false
27
28
 
29
+ # This allows default values to have extended values like arrays and casted
30
+ # values. Extended defaults are still experimental, so enable and test it
31
+ # before using it in prod
32
+ config.use_extended_defaults = false
33
+
28
34
  # Set a list of irregular model name when associated with table names
29
35
  config.irregular_models = {}
30
36
  def config.irregular_models=(hash)
@@ -146,7 +146,7 @@ module Torque
146
146
  auto_cast = _auto_cast_attribute.to_s
147
147
  record_class = _record_class_attribute.to_s
148
148
  return super unless attributes.key?(record_class) &&
149
- attributes.delete(auto_cast) && attributes[record_class] != table_name
149
+ attributes.delete(auto_cast) && attributes[record_class] != table_name
150
150
 
151
151
  klass = casted_dependents[attributes[record_class]]
152
152
  raise_unable_to_cast(attributes[record_class]) if klass.nil?
@@ -56,8 +56,10 @@ module Torque
56
56
  end
57
57
 
58
58
  ::ActiveRecord::Reflection.const_set(:BelongsToManyReflection, BelongsToManyReflection)
59
- ::ActiveRecord::Reflection::AssociationReflection::VALID_AUTOMATIC_INVERSE_MACROS
60
- .push(:belongs_to_many)
59
+
60
+ reflection_class = ::ActiveRecord::Reflection::AssociationReflection
61
+ reflection_class::VALID_AUTOMATIC_INVERSE_MACROS.push(:belongs_to_many) \
62
+ if reflection_class.const_defined?('VALID_AUTOMATIC_INVERSE_MACROS')
61
63
  end
62
64
  end
63
65
  end
@@ -5,6 +5,8 @@ module Torque
5
5
  module Relation
6
6
  module Inheritance
7
7
 
8
+ # REGCLASS = ::Arel.sql('tableoid').cast('regclass')
9
+
8
10
  # :nodoc:
9
11
  def cast_records_value; get_value(:cast_records); end
10
12
  # :nodoc:
@@ -44,14 +46,8 @@ module Torque
44
46
 
45
47
  # Like #cast_records, but modifies relation in place
46
48
  def cast_records!(*types, **options)
47
- record_class = self.class._record_class_attribute
48
-
49
- with!(record_class)
50
- if options[:filter]
51
- table = record_class.to_s.camelize.underscore
52
- where!(table => { record_class => types.map(&:table_name) })
53
- end
54
-
49
+ where!(regclass.cast(:varchar).in(types.map(&:table_name))) if options[:filter]
50
+ self.select_extra_values += [regclass.as(_record_class_attribute.to_s)]
55
51
  self.cast_records_value = (types.present? ? types : model.casted_dependents.values)
56
52
  self
57
53
  end
@@ -109,13 +105,12 @@ module Torque
109
105
  end
110
106
 
111
107
  def build_auto_caster_marker(arel, types)
112
- types = types.map(&:table_name)
113
- type_attribute = self.class._record_class_attribute.to_s
114
- auto_cast_attribute = self.class._auto_cast_attribute.to_s
108
+ attribute = regclass.cast(:varchar).in(types.map(&:table_name))
109
+ attribute.as(self.class._auto_cast_attribute.to_s)
110
+ end
115
111
 
116
- table = ::Arel::Table.new(type_attribute.camelize.underscore)
117
- column = table[type_attribute].in(types)
118
- ::Arel.sql(column.to_sql).as(auto_cast_attribute)
112
+ def regclass
113
+ arel_table['tableoid'].cast(:regclass)
119
114
  end
120
115
 
121
116
  end
@@ -2,6 +2,6 @@
2
2
 
3
3
  module Torque
4
4
  module PostgreSQL
5
- VERSION = '2.1.0'
5
+ VERSION = '2.2.0'
6
6
  end
7
7
  end
@@ -23,7 +23,6 @@ require 'torque/postgresql/auxiliary_statement'
23
23
  require 'torque/postgresql/base'
24
24
  require 'torque/postgresql/inheritance'
25
25
  require 'torque/postgresql/insert_all'
26
- require 'torque/postgresql/coder'
27
26
  require 'torque/postgresql/migration'
28
27
  require 'torque/postgresql/relation'
29
28
  require 'torque/postgresql/reflection'
data/lib/torque/range.rb CHANGED
@@ -17,6 +17,4 @@ module Torque
17
17
  end
18
18
  alias_method :|, :union
19
19
  end
20
-
21
- ::Range.include(Range)
22
20
  end
@@ -0,0 +1,5 @@
1
+ FactoryBot.define do
2
+ factory :item do
3
+ name { Faker::Lorem.sentence }
4
+ end
5
+ end
@@ -0,0 +1,3 @@
1
+ class Item < ActiveRecord::Base
2
+ belongs_to_many :tags
3
+ end
@@ -0,0 +1,3 @@
1
+ class Question < ActiveRecord::Base
2
+ self.implicit_order_column = 'created_at'
3
+ end
@@ -0,0 +1,2 @@
1
+ class QuestionSelect < Question
2
+ end
data/spec/schema.rb CHANGED
@@ -11,13 +11,14 @@
11
11
  # It's strongly recommended that you check this file into your version control system.
12
12
 
13
13
  begin
14
- version = 63
14
+ version = 73
15
15
 
16
16
  raise SystemExit if ActiveRecord::Migrator.current_version == version
17
17
  ActiveRecord::Schema.define(version: version) do
18
18
  self.verbose = false
19
19
 
20
20
  # These are extensions that must be enabled in order to support this database
21
+ enable_extension "pgcrypto"
21
22
  enable_extension "plpgsql"
22
23
 
23
24
  # These are user-defined types used on this database
@@ -102,6 +103,13 @@ begin
102
103
  t.index ["author_id"], name: "index_posts_on_author_id", using: :btree
103
104
  end
104
105
 
106
+ create_table "items", force: :cascade do |t|
107
+ t.string "name"
108
+ t.bigint "tag_ids", array: true, default: "{1}"
109
+ t.datetime "created_at", null: false
110
+ t.datetime "updated_at", null: false
111
+ end
112
+
105
113
  create_table "users", force: :cascade do |t|
106
114
  t.string "name", null: false
107
115
  t.enum "role", subtype: :roles, default: :visitor
@@ -118,6 +126,12 @@ begin
118
126
  t.datetime "updated_at", null: false
119
127
  end
120
128
 
129
+ create_table "questions", id: :uuid, default: -> { "gen_random_uuid()" }, force: :cascade do |t|
130
+ t.string "title"
131
+ t.datetime "created_at", null: false
132
+ t.datetime "updated_at", null: false
133
+ end
134
+
121
135
  create_table "activity_books", force: :cascade, inherits: :activities do |t|
122
136
  t.text "description"
123
137
  t.string "url"
@@ -132,6 +146,10 @@ begin
132
146
 
133
147
  create_table "activity_post_samples", force: :cascade, inherits: :activity_posts
134
148
 
149
+ create_table "question_selects", force: :cascade, inherits: :questions do |t|
150
+ t.string "options", array: true
151
+ end
152
+
135
153
  # create_table "activity_blanks", force: :cascade, inherits: :activities
136
154
 
137
155
  # create_table "activity_images", force: :cascade, inherits: [:activities, :images]
@@ -48,6 +48,36 @@ RSpec.describe 'Arel' do
48
48
  end
49
49
  end
50
50
 
51
+ context 'on default value' do
52
+ let(:connection) { ActiveRecord::Base.connection }
53
+
54
+ before(:context) { Torque::PostgreSQL.config.use_extended_defaults = true }
55
+ after(:context) { Torque::PostgreSQL.config.use_extended_defaults = false }
56
+ after { Author.reset_column_information }
57
+
58
+ it 'does not break jsonb' do
59
+ expect { connection.add_column(:authors, :profile, :jsonb, default: []) }.not_to raise_error
60
+ expect(Author.columns_hash['profile'].default).to eq('[]')
61
+ end
62
+
63
+ it 'works properly when column is an array' do
64
+ expect { connection.add_column(:authors, :tag_ids, :bigint, array: true, default: []) }.not_to raise_error
65
+ expect(Author.columns_hash['tag_ids'].default).to eq([])
66
+ end
67
+
68
+ it 'works with an array with enum values' do
69
+ value = ['visitor', 'assistant']
70
+ expect { connection.add_column(:authors, :roles, :roles, array: true, default: value) }.not_to raise_error
71
+ expect(Author.columns_hash['roles'].default).to eq(value)
72
+ end
73
+
74
+ it 'works with multi dimentional array' do
75
+ value = [['1', '2'], ['3', '4']]
76
+ expect { connection.add_column(:authors, :tag_ids, :string, array: true, default: value) }.not_to raise_error
77
+ expect(Author.columns_hash['tag_ids'].default).to eq(value)
78
+ end
79
+ end
80
+
51
81
  context 'on cast' do
52
82
  it 'provides an array method' do
53
83
  sample1 = ::Arel.array(1, 2, 3, 4)
@@ -147,6 +147,22 @@ RSpec.describe 'BelongsToMany' do
147
147
  expect(record.tags.count).to be_eql(5)
148
148
  end
149
149
 
150
+ it 'does not trigger after commit on the associated record' do
151
+ called = false
152
+
153
+ tag = FactoryBot.create(:tag)
154
+ Tag.after_commit { called = true }
155
+
156
+ expect(called).to be_falsey
157
+
158
+ subject.tags << tag
159
+
160
+ expect(subject.tag_ids).to be_eql([tag.id])
161
+ expect(called).to be_falsey
162
+
163
+ Tag.reset_callbacks(:commit)
164
+ end
165
+
150
166
  it 'can build an associated record' do
151
167
  record = subject.tags.build(name: 'Test')
152
168
  expect(record).to be_a(other)
@@ -225,6 +241,17 @@ RSpec.describe 'BelongsToMany' do
225
241
  expect(subject.tags.size).to be_eql(0)
226
242
  end
227
243
 
244
+ it 'can clear the array' do
245
+ record = Video.create(title: 'B', tags: [initial])
246
+ expect(record.tags.size).to be_eql(1)
247
+
248
+ record.update(tag_ids: [])
249
+ record.reload
250
+
251
+ expect(record.tag_ids).to be_nil
252
+ expect(record.tags.size).to be_eql(0)
253
+ end
254
+
228
255
  it 'can have sum operations' do
229
256
  records = FactoryBot.create_list(:tag, 5)
230
257
  subject.tags.concat(records)
@@ -319,17 +346,11 @@ RSpec.describe 'BelongsToMany' do
319
346
  end
320
347
 
321
348
  context 'When the attribute has a default value' do
322
- after(:all) { Video.reset_column_information }
323
- let(:sql) { %{ALTER TABLE "videos" ALTER COLUMN "tag_ids" SET DEFAULT '{}'::bigint[]} }
324
-
325
- before do
326
- Video.connection.execute(sql)
327
- Video.reset_column_information
328
- end
349
+ subject { FactoryBot.create(:item) }
329
350
 
330
351
  it 'will always return the column default value' do
331
352
  expect(subject.tag_ids).to be_a(Array)
332
- expect(subject.tag_ids).to be_empty
353
+ expect(subject.tag_ids).to be_eql([1])
333
354
  end
334
355
 
335
356
  it 'will keep the value as an array even when the association is cleared' do
@@ -338,12 +359,12 @@ RSpec.describe 'BelongsToMany' do
338
359
 
339
360
  subject.reload
340
361
  expect(subject.tag_ids).to be_a(Array)
341
- expect(subject.tag_ids).not_to be_empty
362
+ expect(subject.tag_ids).not_to be_eql([1, *records.map(&:id)])
342
363
 
343
364
  subject.tags.clear
344
365
  subject.reload
345
366
  expect(subject.tag_ids).to be_a(Array)
346
- expect(subject.tag_ids).to be_empty
367
+ expect(subject.tag_ids).to be_eql([1])
347
368
  end
348
369
  end
349
370
 
@@ -266,6 +266,15 @@ RSpec.describe 'Period' do
266
266
 
267
267
  instance.period = 4.hour.from_now.utc..6.hour.from_now.utc
268
268
  expect(instance).not_to be_current_period
269
+
270
+ instance.period = [nil, 4.hours.ago.utc]
271
+ expect(instance).not_to be_current_period
272
+
273
+ instance.period = [4.hours.from_now.utc, nil]
274
+ expect(instance).not_to be_current_period
275
+
276
+ instance.period = [nil, nil]
277
+ expect(instance).to be_current_period
269
278
  end
270
279
 
271
280
  it 'checks fro current based on a value' do
@@ -1,6 +1,6 @@
1
1
  require 'spec_helper'
2
2
 
3
- RSpec.describe 'Range' do
3
+ RSpec.xdescribe 'Range' do
4
4
  let(:sample) { (5..15) }
5
5
 
6
6
  it 'has intersection' do