I had a problem with my project. I didn’t want help fixing it, though, I wanted understanding how to debug it and fix it myself because I anticipated that I would encounter similar problems in the future.
Herein follows a tale of woe. Interested parties may be interested in following it to understand how someone not familiar with the software approaches the software. Other interested parties trying to figure out associations might also benefit. After the tale of woe I comment on how documentation could be improved to help others avoid this trouble.
… This material will be split as “new users can only put two links in a post”. Curse you, Discourse. All my links are to Github under the rom-rb project namespace.
Tale of Woe
I have a dry-web-roda template application, and I’m playing around with some domain-driven design, so my application itsuki
has a couple of tables like bookings
and booking_requests
. The idea is that the booking itself has a top-level object, and various requests are made to put it in a certain state, like the user making the booking requesting certain dates and the administrator user approving them.
I’ve gotten migrations all sorted, the SQL tables look the way I want them to (for the moment), I’ve got a couple of relation classes describing them and setting defaults on fields like created_at
, and now I’m trying to write an operation that represents the initial request, where a user submits a form and the application creates a booking
with a booking_request
associated with it.
My operation
class looks somewhat like this:
booking_repo.transaction do
booking = bookings_repo.new_booking
STDERR.puts booking.inspect
booking_request = booking_requests_repo.changeset(
message: params['message'],
user_initiated: true,
state: 0,
)
STDERR.puts booking_request.inspect
assoc = booking_request.associate(booking, :booking)
STDERR.puts assoc.inspect
assoc.commit
end
When this code runs, I get output something like so:
#<ROM::Struct::Booking id=8 active=true reference="B-2017-6DLD8X" created_at=2017-07-23 13:34:02 +0100>
#<ROM::Changeset::Create relation=ROM::Relation::Name(booking_requests) data={:message=>"", :user_initiated=>true, :state=>0}>
#<ROM::Changeset::Associated:0x007faddef44168 @__options__={:left=>#<ROM::Changeset::Create relation=ROM::Relation::Name(booking_requests) data={:message=>"", :user_initiated=>true, :state=>0}>, :associations=>{:booking=>#<ROM::Struct::Booking id=8 active=true reference="B-2017-6DLD8X" created_at=2017-07-23 13:34:02 +0100>}}, @left=#<ROM::Changeset::Create relation=ROM::Relation::Name(booking_requests) data={:message=>"", :user_initiated=>true, :state=>0}>, @associations={:booking=>#<ROM::Struct::Booking id=8 active=true reference="B-2017-6DLD8X" created_at=2017-07-23 13:34:02 +0100>}>
ROM::SQL::NotNullConstraintError: PG::NotNullViolation: ERROR: null value in column "booking_id" violates not-null constraint
DETAIL: Failing row contains (5, null, 2017-07-23 12:34:02.412665, t, null, USD, 0, ).
In short, the foreign key booking_id
has not been set on the booking_request
object.