ankane/neighbor

Support t.vector ... array: true in rails schema

Opened this issue · 0 comments

Sometimes, one would like to save an array of embeddings, as opposed to a single embedding. This is particularly useful when you have a dynamic length, such as a t.text "content", array: true counterpart.

    t.vector "embeddings", limit: 1024, array: true

Failing callstack:

(ruby) self.embeddings = array_of_embeddings
(ruby) save!
eval error: can't cast Float to vector
  /Users/dimroc/.gem/ruby/3.3.4/gems/neighbor-0.4.2/lib/neighbor/type/vector.rb:23:in `cast_value'
  /Users/dimroc/.gem/ruby/3.3.4/gems/activemodel-7.1.4/lib/active_model/type/value.rb:58:in `cast'
  /Users/dimroc/.gem/ruby/3.3.4/gems/activerecord-7.1.4/lib/active_record/connection_adapters/postgresql/oid/array.rb:84:in `public_send'
  /Users/dimroc/.gem/ruby/3.3.4/gems/activerecord-7.1.4/lib/active_record/connection_adapters/postgresql/oid/array.rb:84:in `type_cast_array'
  /Users/dimroc/.gem/ruby/3.3.4/gems/activerecord-7.1.4/lib/active_record/connection_adapters/postgresql/oid/array.rb:82:in `block in type_cast_array'
  /Users/dimroc/.gem/ruby/3.3.4/gems/activerecord-7.1.4/lib/active_record/connection_adapters/postgresql/oid/array.rb:82:in `map'
  /Users/dimroc/.gem/ruby/3.3.4/gems/activerecord-7.1.4/lib/active_record/connection_adapters/postgresql/oid/array.rb:82:in `type_cast_array'
  /Users/dimroc/.gem/ruby/3.3.4/gems/activerecord-7.1.4/lib/active_record/connection_adapters/postgresql/oid/array.rb:82:in `block in type_cast_array'
  /Users/dimroc/.gem/ruby/3.3.4/gems/activerecord-7.1.4/lib/active_record/connection_adapters/postgresql/oid/array.rb:82:in `map'
  /Users/dimroc/.gem/ruby/3.3.4/gems/activerecord-7.1.4/lib/active_record/connection_adapters/postgresql/oid/array.rb:82:in `type_cast_array'
  /Users/dimroc/.gem/ruby/3.3.4/gems/activerecord-7.1.4/lib/active_record/connection_adapters/postgresql/oid/array.rb:44:in `cast'
  /Users/dimroc/.gem/ruby/3.3.4/gems/activemodel-7.1.4/lib/active_model/attribute.rb:199:in `type_cast'
  /Users/dimroc/.gem/ruby/3.3.4/gems/activemodel-7.1.4/lib/active_model/attribute.rb:43:in `value'
  /Users/dimroc/.gem/ruby/3.3.4/gems/activemodel-7.1.4/lib/active_model/attribute_set/builder.rb:43:in `fetch_value'
  /Users/dimroc/.gem/ruby/3.3.4/gems/activerecord-7.1.4/lib/active_record/transactions.rb:421:in `block in restore_transaction_record_state'
  /Users/dimroc/.gem/ruby/3.3.4/gems/activemodel-7.1.4/lib/active_model/attribute_set.rb:98:in `transform_values'
  /Users/dimroc/.gem/ruby/3.3.4/gems/activemodel-7.1.4/lib/active_model/attribute_set.rb:98:in `map'
  /Users/dimroc/.gem/ruby/3.3.4/gems/activerecord-7.1.4/lib/active_record/transactions.rb:420:in `restore_transaction_record_state'
  /Users/dimroc/.gem/ruby/3.3.4/gems/activerecord-7.1.4/lib/active_record/transactions.rb:345:in `rolledback!'
  /Users/dimroc/.gem/ruby/3.3.4/gems/activerecord-7.1.4/lib/active_record/connection_adapters/abstract/transaction.rb:200:in `block in rollback_records'
  /Users/dimroc/.gem/ruby/3.3.4/gems/activerecord-7.1.4/lib/active_record/connection_adapters/abstract/transaction.rb:263:in `run_action_on_records'
  /Users/dimroc/.gem/ruby/3.3.4/gems/activerecord-7.1.4/lib/active_record/connection_adapters/abstract/transaction.rb:199:in `rollback_records'
  /Users/dimroc/.gem/ruby/3.3.4/gems/activerecord-7.1.4/lib/active_record/connection_adapters/abstract/transaction.rb:527:in `block in rollback_transaction'
  /Users/dimroc/.gem/ruby/3.3.4/gems/activesupport-7.1.4/lib/active_support/concurrency/load_interlock_aware_monitor.rb:23:in `handle_interrupt'
  /Users/dimroc/.gem/ruby/3.3.4/gems/activesupport-7.1.4/lib/active_support/concurrency/load_interlock_aware_monitor.rb:23:in `block in synchronize'
  /Users/dimroc/.gem/ruby/3.3.4/gems/activesupport-7.1.4/lib/active_support/concurrency/load_interlock_aware_monitor.rb:19:in `handle_interrupt'
  /Users/dimroc/.gem/ruby/3.3.4/gems/activesupport-7.1.4/lib/active_support/concurrency/load_interlock_aware_monitor.rb:19:in `synchronize'
  /Users/dimroc/.gem/ruby/3.3.4/gems/activerecord-7.1.4/lib/active_record/connection_adapters/abstract/transaction.rb:520:in `rollback_transaction'
  /Users/dimroc/.gem/ruby/3.3.4/gems/activerecord-7.1.4/lib/active_record/connection_adapters/abstract/transaction.rb:539:in `rescue in block in within_new_transaction'
  /Users/dimroc/.gem/ruby/3.3.4/gems/activerecord-7.1.4/lib/active_record/connection_adapters/abstract/transaction.rb:538:in `block in within_new_transaction'
  /Users/dimroc/.gem/ruby/3.3.4/gems/activesupport-7.1.4/lib/active_support/concurrency/load_interlock_aware_monitor.rb:23:in `handle_interrupt'
  /Users/dimroc/.gem/ruby/3.3.4/gems/activesupport-7.1.4/lib/active_support/concurrency/load_interlock_aware_monitor.rb:23:in `block in synchronize'
  /Users/dimroc/.gem/ruby/3.3.4/gems/activesupport-7.1.4/lib/active_support/concurrency/load_interlock_aware_monitor.rb:19:in `handle_interrupt'
  /Users/dimroc/.gem/ruby/3.3.4/gems/activesupport-7.1.4/lib/active_support/concurrency/load_interlock_aware_monitor.rb:19:in `synchronize'
  /Users/dimroc/.gem/ruby/3.3.4/gems/activerecord-7.1.4/lib/active_record/connection_adapters/abstract/transaction.rb:532:in `within_new_transaction'
  /Users/dimroc/.gem/ruby/3.3.4/gems/activerecord-7.1.4/lib/active_record/connection_adapters/abstract/database_statements.rb:344:in `transaction'
  /Users/dimroc/.gem/ruby/3.3.4/gems/activerecord-7.1.4/lib/active_record/transactions.rb:361:in `with_transaction_returning_status'
  /Users/dimroc/.gem/ruby/3.3.4/gems/activerecord-7.1.4/lib/active_record/transactions.rb:313:in `save!'
  /Users/dimroc/.gem/ruby/3.3.4/gems/activerecord-7.1.4/lib/active_record/suppressor.rb:56:in `save!'