brendon / ranked-model

An acts_as_sortable/acts_as_list replacement built for Rails 4+
https://github.com/mixonic/ranked-model
MIT License
1.09k stars 134 forks source link

Conficts with Mobility JSONB backend #159

Closed JanStevens closed 5 months ago

JanStevens commented 5 years ago

Hello,

when using mobility (json backend) in combination with ranked model, we see that when we update the position ranked model also tries to save the translations columns as null (instead of an empty hash which is the default behaviour)

Following test case shows the issue, funny enough if I remove the with_same option it all works fine and placeholder does not get updated. You need a database called scratches with postgres to run the file.

require "bundler/inline"

gemfile(true) do
  source "https://rubygems.org"

  git_source(:github) { |repo| "https://github.com/#{repo}.git" }

  # Activate the gem you are reporting the issue against.
  gem "activerecord", "~> 5.2.0"
  gem "pg"
  gem 'ranked-model'
  gem 'mobility'
  gem 'enumerize'
end

require "active_record"
require "minitest/autorun"
require "logger"

Mobility.configure do |config|
  config.default_backend = :jsonb
  config.accessor_method = :translates
  config.query_method = :i18n
  config.default_options[:locale_accessors] = true
  config.default_options[:fallbacks] = true
  config.default_options[:dirty] = true
end

# This connection will do for database-independent bug reports.
ActiveRecord::Base.establish_connection(adapter: "postgresql", database: "scratches")
ActiveRecord::Base.logger = Logger.new(STDOUT)

ActiveRecord::Schema.define do
  drop_table :registration_form_fields, if_exists: true
  drop_table :registration_forms, if_exists: true

  create_table :registration_forms, force: true do |t|
    t.string :name, null: false
  end

  create_table :registration_form_fields, force: true do |t|
    t.string :name, null: false
    t.jsonb :label, default: {}, null: false
    t.jsonb :placeholder, default: {}, null: false
    t.integer :row_order
    t.belongs_to :registration_form, foreign_key: true, index: true, null: false
  end
end

class RegistrationForm < ActiveRecord::Base
  has_many :fields, class_name: 'RegistrationFormField', dependent: :destroy, inverse_of: :registration_form
end

class RegistrationFormField < ActiveRecord::Base
  include RankedModel
  extend Mobility

  belongs_to :registration_form

  ranks :row_order, with_same: :registration_form_id

  translates :label, type: :string
  translates :placeholder, type: :string
end

class BugTest < Minitest::Test
  def test_association_stuff
    registration_from = RegistrationForm.create!(name: 'jefke')
    puts registration_from.fields.create!(name: 'email', label: 'email')

    registration_from.fields.first.reload

    registration_from.fields.first.update!(row_order_position: 1)
  end
end
brendon commented 5 years ago

Hi @JanStevens, thanks for the bug report. Would you mind posting sql logs of what happens in both scenarios? Just to try and see the difference.

JanStevens commented 5 years ago
Fetching gem metadata from https://rubygems.org/...............
Resolving dependencies...
Using concurrent-ruby 1.1.5
Using i18n 1.7.0
Using minitest 5.13.0
Using thread_safe 0.3.6
Using tzinfo 1.2.5
Using activesupport 5.2.3
Using activemodel 5.2.3
Using arel 9.0.0
Using activerecord 5.2.3
Using bundler 2.0.2
Using enumerize 2.3.1
Using rack 2.0.7
Using request_store 1.4.1
Using mobility 0.8.9
Using pg 1.1.4
Using ranked-model 0.4.4
-- drop_table(:registration_form_fields, {:if_exists=>true})
D, [2019-11-22T15:01:38.320320 #69260] DEBUG -- :    (4.5ms)  DROP TABLE IF EXISTS "registration_form_fields"
   -> 0.0177s
-- drop_table(:registration_forms, {:if_exists=>true})
D, [2019-11-22T15:01:38.322600 #69260] DEBUG -- :    (2.1ms)  DROP TABLE IF EXISTS "registration_forms"
   -> 0.0022s
-- create_table(:registration_forms, {:force=>true})
D, [2019-11-22T15:01:38.323027 #69260] DEBUG -- :    (0.1ms)  DROP TABLE IF EXISTS "registration_forms"
D, [2019-11-22T15:01:38.326803 #69260] DEBUG -- :    (3.6ms)  CREATE TABLE "registration_forms" ("id" bigserial primary key, "name" character varying NOT NULL)
   -> 0.0042s
-- create_table(:registration_form_fields, {:force=>true})
D, [2019-11-22T15:01:38.327406 #69260] DEBUG -- :    (0.2ms)  DROP TABLE IF EXISTS "registration_form_fields"
D, [2019-11-22T15:01:38.331169 #69260] DEBUG -- :    (3.1ms)  CREATE TABLE "registration_form_fields" ("id" bigserial primary key, "name" character varying NOT NULL, "label" jsonb DEFAULT '{}' NOT NULL, "placeholder" jsonb DEFAULT '{}' NOT NULL, "row_order" integer, "registration_form_id" bigint NOT NULL, CONSTRAINT "fk_rails_68849c03b8"
FOREIGN KEY ("registration_form_id")
  REFERENCES "registration_forms" ("id")
)
D, [2019-11-22T15:01:38.333765 #69260] DEBUG -- :    (0.8ms)  CREATE  INDEX  "index_registration_form_fields_on_registration_form_id" ON "registration_form_fields"  ("registration_form_id")
   -> 0.0069s
D, [2019-11-22T15:01:38.432931 #69260] DEBUG -- :   ActiveRecord::InternalMetadata Load (0.3ms)  SELECT  "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2  [["key", "environment"], ["LIMIT", 1]]
D, [2019-11-22T15:01:38.436806 #69260] DEBUG -- :    (0.1ms)  BEGIN
D, [2019-11-22T15:01:38.437355 #69260] DEBUG -- :    (0.1ms)  COMMIT
Run options: --seed 54095

# Running:

D, [2019-11-22T15:01:38.469237 #69260] DEBUG -- :    (0.1ms)  BEGIN
D, [2019-11-22T15:01:38.470139 #69260] DEBUG -- :   RegistrationForm Create (0.4ms)  INSERT INTO "registration_forms" ("name") VALUES ($1) RETURNING "id"  [["name", "jefke"]]
D, [2019-11-22T15:01:38.470416 #69260] DEBUG -- :    (0.1ms)  COMMIT
D, [2019-11-22T15:01:38.481776 #69260] DEBUG -- :    (0.2ms)  BEGIN
D, [2019-11-22T15:01:38.483644 #69260] DEBUG -- :   RegistrationFormField Load (0.9ms)  SELECT "registration_form_fields"."id", "registration_form_fields"."row_order", "registration_form_fields"."registration_form_id" FROM "registration_form_fields" WHERE "registration_form_fields"."registration_form_id" = $1 ORDER BY "registration_form_fields"."row_order" ASC  [["registration_form_id", 1]]
D, [2019-11-22T15:01:38.484670 #69260] DEBUG -- :   RegistrationFormField Load (0.2ms)  SELECT  "registration_form_fields"."id", "registration_form_fields"."row_order", "registration_form_fields"."registration_form_id" FROM "registration_form_fields" WHERE "registration_form_fields"."registration_form_id" = $1 AND "registration_form_fields"."row_order" = $2 ORDER BY "registration_form_fields"."id" ASC LIMIT $3  [["registration_form_id", 1], ["row_order", 0], ["LIMIT", 1]]
D, [2019-11-22T15:01:38.486095 #69260] DEBUG -- :   RegistrationFormField Create (0.8ms)  INSERT INTO "registration_form_fields" ("name", "label", "placeholder", "row_order", "registration_form_id") VALUES ($1, $2, $3, $4, $5) RETURNING "id"  [["name", "email"], ["label", "{\"en\":\"email\"}"], ["placeholder", nil], ["row_order", 0], ["registration_form_id", 1]]
D, [2019-11-22T15:01:38.486298 #69260] DEBUG -- :    (0.1ms)  ROLLBACK
E

Finished in 0.022021s, 45.4112 runs/s, 0.0000 assertions/s.

  1) Error:
BugTest#test_association_stuff:
ActiveRecord::NotNullViolation: PG::NotNullViolation: ERROR:  null value in column "placeholder" violates not-null constraint
DETAIL:  Failing row contains (1, email, {"en": "email"}, null, 0, 1).
: INSERT INTO "registration_form_fields" ("name", "label", "placeholder", "row_order", "registration_form_id") VALUES ($1, $2, $3, $4, $5) RETURNING "id"
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/postgresql_adapter.rb:611:in `async_exec_params'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/postgresql_adapter.rb:611:in `block (2 levels) in exec_no_cache'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activesupport-5.2.3/lib/active_support/dependencies/interlock.rb:48:in `block in permit_concurrent_loads'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activesupport-5.2.3/lib/active_support/concurrency/share_lock.rb:187:in `yield_shares'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activesupport-5.2.3/lib/active_support/dependencies/interlock.rb:47:in `permit_concurrent_loads'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/postgresql_adapter.rb:610:in `block in exec_no_cache'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/abstract_adapter.rb:581:in `block (2 levels) in log'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/2.6.0/monitor.rb:230:in `mon_synchronize'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/abstract_adapter.rb:580:in `block in log'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activesupport-5.2.3/lib/active_support/notifications/instrumenter.rb:23:in `instrument'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/abstract_adapter.rb:571:in `log'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/postgresql_adapter.rb:609:in `exec_no_cache'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/postgresql_adapter.rb:598:in `execute_and_clear'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/postgresql/database_statements.rb:81:in `exec_query'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/abstract/database_statements.rb:130:in `exec_insert'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/postgresql/database_statements.rb:115:in `exec_insert'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/abstract/database_statements.rb:162:in `insert'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/abstract/query_cache.rb:21:in `insert'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/persistence.rb:187:in `_insert_record'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/persistence.rb:734:in `_create_record'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/counter_cache.rb:184:in `_create_record'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/locking/optimistic.rb:70:in `_create_record'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/attribute_methods/dirty.rb:140:in `_create_record'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/callbacks.rb:346:in `block in _create_record'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activesupport-5.2.3/lib/active_support/callbacks.rb:98:in `run_callbacks'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activesupport-5.2.3/lib/active_support/callbacks.rb:816:in `_run_create_callbacks'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/callbacks.rb:346:in `_create_record'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/timestamp.rb:102:in `_create_record'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/persistence.rb:705:in `create_or_update'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/callbacks.rb:342:in `block in create_or_update'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activesupport-5.2.3/lib/active_support/callbacks.rb:132:in `run_callbacks'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activesupport-5.2.3/lib/active_support/callbacks.rb:816:in `_run_save_callbacks'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/callbacks.rb:342:in `create_or_update'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/persistence.rb:308:in `save!'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/validations.rb:52:in `save!'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/transactions.rb:315:in `block in save!'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/transactions.rb:387:in `block in with_transaction_returning_status'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/abstract/database_statements.rb:265:in `transaction'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/transactions.rb:212:in `transaction'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/transactions.rb:385:in `with_transaction_returning_status'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/transactions.rb:315:in `save!'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/suppressor.rb:48:in `save!'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/associations/collection_association.rb:375:in `insert_record'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/associations/has_many_association.rb:36:in `insert_record'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/associations/collection_association.rb:362:in `block (2 levels) in _create_record'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/associations/collection_association.rb:458:in `replace_on_target'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/associations/collection_association.rb:283:in `add_to_target'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/associations/collection_association.rb:361:in `block in _create_record'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/associations/collection_association.rb:135:in `block in transaction'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/abstract/database_statements.rb:267:in `block in transaction'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/abstract/transaction.rb:239:in `block in within_new_transaction'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/2.6.0/monitor.rb:230:in `mon_synchronize'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/abstract/transaction.rb:236:in `within_new_transaction'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/connection_adapters/abstract/database_statements.rb:267:in `transaction'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/transactions.rb:212:in `transaction'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/associations/collection_association.rb:134:in `transaction'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/associations/collection_association.rb:359:in `_create_record'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/associations/has_many_association.rb:124:in `_create_record'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/associations/association.rb:194:in `create!'
    /Users/fritz/.asdf/installs/ruby/2.6.3/lib/ruby/gems/2.6.0/gems/activerecord-5.2.3/lib/active_record/associations/collection_proxy.rb:366:in `create!'
    /Users/fritz/Library/Preferences/RubyMine2019.2/scratches/scratch_74.rb:70:in `test_association_stuff'

1 runs, 0 assertions, 0 failures, 1 errors, 0 skips

And when removing the with_same option

Fetching gem metadata from https://rubygems.org/...............
Resolving dependencies...
Using concurrent-ruby 1.1.5
Using i18n 1.7.0
Using minitest 5.13.0
Using thread_safe 0.3.6
Using tzinfo 1.2.5
Using activesupport 5.2.3
Using activemodel 5.2.3
Using arel 9.0.0
Using activerecord 5.2.3
Using bundler 2.0.2
Using enumerize 2.3.1
Using rack 2.0.7
Using request_store 1.4.1
Using mobility 0.8.9
Using pg 1.1.4
Using ranked-model 0.4.4
-- drop_table(:registration_form_fields, {:if_exists=>true})
D, [2019-11-22T15:02:13.897572 #71127] DEBUG -- :    (6.5ms)  DROP TABLE IF EXISTS "registration_form_fields"
   -> 0.0300s
-- drop_table(:registration_forms, {:if_exists=>true})
D, [2019-11-22T15:02:13.900256 #71127] DEBUG -- :    (2.4ms)  DROP TABLE IF EXISTS "registration_forms"
   -> 0.0026s
-- create_table(:registration_forms, {:force=>true})
D, [2019-11-22T15:02:13.900784 #71127] DEBUG -- :    (0.1ms)  DROP TABLE IF EXISTS "registration_forms"
D, [2019-11-22T15:02:13.909001 #71127] DEBUG -- :    (8.0ms)  CREATE TABLE "registration_forms" ("id" bigserial primary key, "name" character varying NOT NULL)
   -> 0.0087s
-- create_table(:registration_form_fields, {:force=>true})
D, [2019-11-22T15:02:13.910088 #71127] DEBUG -- :    (0.4ms)  DROP TABLE IF EXISTS "registration_form_fields"
D, [2019-11-22T15:02:13.914536 #71127] DEBUG -- :    (3.6ms)  CREATE TABLE "registration_form_fields" ("id" bigserial primary key, "name" character varying NOT NULL, "label" jsonb DEFAULT '{}' NOT NULL, "placeholder" jsonb DEFAULT '{}' NOT NULL, "row_order" integer, "registration_form_id" bigint NOT NULL, CONSTRAINT "fk_rails_68849c03b8"
FOREIGN KEY ("registration_form_id")
  REFERENCES "registration_forms" ("id")
)
D, [2019-11-22T15:02:13.918029 #71127] DEBUG -- :    (0.8ms)  CREATE  INDEX  "index_registration_form_fields_on_registration_form_id" ON "registration_form_fields"  ("registration_form_id")
   -> 0.0089s
D, [2019-11-22T15:02:13.957011 #71127] DEBUG -- :   ActiveRecord::InternalMetadata Load (0.4ms)  SELECT  "ar_internal_metadata".* FROM "ar_internal_metadata" WHERE "ar_internal_metadata"."key" = $1 LIMIT $2  [["key", "environment"], ["LIMIT", 1]]
D, [2019-11-22T15:02:14.047281 #71127] DEBUG -- :    (0.1ms)  BEGIN
D, [2019-11-22T15:02:14.047870 #71127] DEBUG -- :    (0.1ms)  COMMIT
Run options: --seed 44802

# Running:

D, [2019-11-22T15:02:14.091214 #71127] DEBUG -- :    (0.1ms)  BEGIN
D, [2019-11-22T15:02:14.092549 #71127] DEBUG -- :   RegistrationForm Create (0.8ms)  INSERT INTO "registration_forms" ("name") VALUES ($1) RETURNING "id"  [["name", "jefke"]]
D, [2019-11-22T15:02:14.093005 #71127] DEBUG -- :    (0.2ms)  COMMIT
D, [2019-11-22T15:02:14.110963 #71127] DEBUG -- :    (0.1ms)  BEGIN
D, [2019-11-22T15:02:14.111979 #71127] DEBUG -- :   RegistrationFormField Load (0.4ms)  SELECT "registration_form_fields"."id", "registration_form_fields"."row_order" FROM "registration_form_fields" ORDER BY "registration_form_fields"."row_order" ASC
D, [2019-11-22T15:02:14.113170 #71127] DEBUG -- :   RegistrationFormField Load (0.4ms)  SELECT  "registration_form_fields"."id", "registration_form_fields"."row_order" FROM "registration_form_fields" WHERE "registration_form_fields"."row_order" = $1 ORDER BY "registration_form_fields"."id" ASC LIMIT $2  [["row_order", 0], ["LIMIT", 1]]
D, [2019-11-22T15:02:14.114491 #71127] DEBUG -- :   RegistrationFormField Create (0.6ms)  INSERT INTO "registration_form_fields" ("name", "label", "row_order", "registration_form_id") VALUES ($1, $2, $3, $4) RETURNING "id"  [["name", "email"], ["label", "{\"en\":\"email\"}"], ["row_order", 0], ["registration_form_id", 1]]
D, [2019-11-22T15:02:14.115019 #71127] DEBUG -- :    (0.1ms)  COMMIT
#<RegistrationFormField:0x00007fed21726f30>
D, [2019-11-22T15:02:14.115934 #71127] DEBUG -- :   RegistrationFormField Load (0.2ms)  SELECT  "registration_form_fields".* FROM "registration_form_fields" WHERE "registration_form_fields"."registration_form_id" = $1 ORDER BY "registration_form_fields"."id" ASC LIMIT $2  [["registration_form_id", 1], ["LIMIT", 1]]
D, [2019-11-22T15:02:14.116733 #71127] DEBUG -- :   RegistrationFormField Load (0.1ms)  SELECT  "registration_form_fields".* FROM "registration_form_fields" WHERE "registration_form_fields"."id" = $1 LIMIT $2  [["id", 1], ["LIMIT", 1]]
D, [2019-11-22T15:02:14.117315 #71127] DEBUG -- :   RegistrationFormField Load (0.1ms)  SELECT  "registration_form_fields".* FROM "registration_form_fields" WHERE "registration_form_fields"."registration_form_id" = $1 ORDER BY "registration_form_fields"."id" ASC LIMIT $2  [["registration_form_id", 1], ["LIMIT", 1]]
D, [2019-11-22T15:02:14.117558 #71127] DEBUG -- :    (0.1ms)  BEGIN
D, [2019-11-22T15:02:14.118409 #71127] DEBUG -- :   RegistrationFormField Load (0.1ms)  SELECT  "registration_form_fields"."id", "registration_form_fields"."row_order" FROM "registration_form_fields" WHERE "registration_form_fields"."id" != $1 ORDER BY "registration_form_fields"."row_order" ASC LIMIT $2 OFFSET $3  [["id", 1], ["LIMIT", 2], ["OFFSET", 0]]
D, [2019-11-22T15:02:14.118842 #71127] DEBUG -- :   RegistrationFormField Load (0.1ms)  SELECT "registration_form_fields"."id", "registration_form_fields"."row_order" FROM "registration_form_fields" WHERE "registration_form_fields"."id" != $1 ORDER BY "registration_form_fields"."row_order" ASC  [["id", 1]]
D, [2019-11-22T15:02:14.119414 #71127] DEBUG -- :   RegistrationFormField Load (0.1ms)  SELECT  "registration_form_fields"."id", "registration_form_fields"."row_order" FROM "registration_form_fields" WHERE "registration_form_fields"."id" != $1 AND "registration_form_fields"."row_order" = $2 ORDER BY "registration_form_fields"."id" ASC LIMIT $3  [["id", 1], ["row_order", 0], ["LIMIT", 1]]
D, [2019-11-22T15:02:14.119987 #71127] DEBUG -- :   RegistrationFormField Update (0.2ms)  UPDATE "registration_form_fields" SET "row_order" = $1 WHERE "registration_form_fields"."id" = $2  [["row_order", 0], ["id", 1]]
D, [2019-11-22T15:02:14.120265 #71127] DEBUG -- :    (0.1ms)  COMMIT
.

Finished in 0.034412s, 29.0596 runs/s, 0.0000 assertions/s.

1 runs, 0 assertions, 0 failures, 0 errors, 0 skips
brendon commented 5 years ago

Looks like a bit of a mystery to me! :) For some reason the placeholder is being triggered as having been changed. I can't see anywhere in our code where we're doing this.

If you don't mind doing some debugging, I would look for when that column is being marked as dirty. That should help narrow down what code is causing the problem. It's strange because ranked-model isn't being told to touch that column at all.

JanStevens commented 5 years ago

Yea I have no idea how to really do that in debugging land 😅

brendon commented 5 years ago

You could try overriding the placeholder_will_change! method so that it raises an error when it's triggered. You could then see a stacktrace of what code triggered the method. There's probably better ways but that was what came to mind.

brendon commented 5 months ago

Since there was no further communication I'll close the issue.