Sure thing,

*DB setup*

require 'sequel'
DB = Sequel.postgres(database: 'sequel_test', host: 'localhost', user: 
'postgres')

*Migration*

Sequel.migration do
  change do
    create_table(:orders) do
      primary_key :id
    end

    create_table(:payments) do
      primary_key :id
      foreign_key :order_id, :orders, null: false, index: { unique: true }
    end
  end
end

*Example*

require './db'

class Payment < Sequel::Model
end

class Order < Sequel::Model
  one_to_one :payment
end

#####
# Example 1: Assigning an already existing one_to_one relation using the 
setter causes (incorrect in my opinion) not null error on FK
#####

o = Order.create
o.payment = Payment.new

# Following line fails with ERROR: null value in column "order_id" of 
relation "payments" violates not-null constraint (PG::NotNullViolation) 
DETAIL: Failing row contains (1, null).
o.payment = Payment.new

# The above generates the following logs in Postgres:
# Feb 11 13:32:24 hp postgres[156074]: 2021-02-11 13:32:24.769 CST [156074] 
ERROR: null value in column "order_id" of relation "payments" violates 
not-null constraint
# Feb 11 13:32:24 hp postgres[156074]: 2021-02-11 13:32:24.769 CST [156074] 
DETAIL: Failing row contains (7, null).
# Feb 11 13:32:24 hp postgres[156074]: 2021-02-11 13:32:24.769 CST [156074] 
STATEMENT: UPDATE "payments" SET "order_id" = NULL WHERE ("order_id" = 6)

#####
# Example 2: Assigning an already existing one_to_one relation without 
using the setter results in correct unique constraint error on FK
#####

o = Order.create
Payment.create(order_id: o.id)
# Fails with ERROR: duplicate key value violates unique constraint 
"payments_order_id_index" (Sequel::UniqueConstraintViolation) DETAIL: Key 
(order_id)=(2) already exists.

Payment.create(order_id: o.id)
# The above generates the following logs in Postgres:
# Feb 11 13:32:41 hp postgres[156216]: 2021-02-11 13:32:41.234 CST [156216] 
ERROR: duplicate key value violates unique constraint 
"payments_order_id_index"
# Feb 11 13:32:41 hp postgres[156216]: 2021-02-11 13:32:41.234 CST [156216] 
DETAIL: Key (order_id)=(7) already exists.
# Feb 11 13:32:41 hp postgres[156216]: 2021-02-11 13:32:41.234 CST [156216] 
STATEMENT: INSERT INTO "payments" ("order_id") VALUES (7) RETURNING *

On Thursday, 11 February 2021 at 14:36:29 UTC+8 Jeremy Evans wrote:

> On Wed, Feb 10, 2021 at 9:37 PM Dawid Janczak <[email protected]> wrote:
>
>> Huh I just checked and oddly doing `order = Payment.new` twice issues 
>> `UPDATE`, not `INSERT`. I created a small script with some comments here: 
>> https://github.com/DawidJanczak/sequel-test-one-to-one/blob/main/sequel_one_to_one.rb
>>  
>> There is also a migration inside `migrations` directory.
>>
>> Please let me know if you need anything else, thanks!
>>
>
> Please post your minimal self-contained example inline as a response.
>
> Thanks,
> Jeremy 
>

-- 
You received this message because you are subscribed to the Google Groups 
"sequel-talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email 
to [email protected].
To view this discussion on the web visit 
https://groups.google.com/d/msgid/sequel-talk/65a4152f-00ea-487a-a048-57173250a582n%40googlegroups.com.

Reply via email to