composite-primary-keys / composite_primary_keys

Composite Primary Keys support for Active Record
1.03k stars 351 forks source link

Error when creating records using version 11.3.1 `NoMethodError: undefined method 'zip' for nil:NilClass` #569

Closed magec closed 2 years ago

magec commented 2 years ago

Hello!

First of all, thanks for the gem!

Today I was trying to migrate a rails app from 5.1 to 5.2 and faced an issue related to composite_primary_keys.

I am consistently getting:

NoMethodError: undefined method `zip' for nil:NilClass
lib/ruby/gems/2.6.0/gems/composite_primary_keys-11.3.1/lib/composite_primary_keys/persistence.rb:69:in `_create_record'

When trying to create a new record using composite primary key

The offending line is this one

I did an small fix like:


    def _create_record(attribute_names = self.attribute_names)
      attribute_names &= self.class.column_names
      attributes_values = attributes_with_values_for_create(attribute_names)

      new_id = self.class._insert_record(attributes_values)

      # CPK
      if self.composite?
        self.id = if self.id.present?
                    # Merge together the specified id with the new id (specified id gets precedence)
                    self.id.zip(Array(new_id)).map {|id1, id2| (id1 || id2)}
                  else
                    new_id
                  end
      else
        self.id ||= new_id if self.class.primary_key
      end

      @new_record = false

      yield(self) if block_given?

      id
    end

And it seemed to work, but I didn't have time to really get into the thing. Any ideas on what this could be happening? I can't see any issue related to the one I'm having.

cfis commented 2 years ago

Looking at the code, I would guess the table doesn't have a primary key. Is that the case?

magec commented 2 years ago

The description of the table is as follows:

   Column   |            Type             | Collation | Nullable |      Default       | Storage  | Stats target | Description
------------+-----------------------------+-----------+----------+--------------------+----------+--------------+-------------
 name       | character varying           |           |          |                    | extended |              |
 created_at | timestamp without time zone |           |          |                    | plain    |              |
 updated_at | timestamp without time zone |           |          |                    | plain    |              |
 id         | uuid                        |           | not null | uuid_generate_v4() | plain    |              |
 app_id     | uuid                        |           | not null |                    | plain    |              |
 read_only  | boolean                     |           |          | false              | plain    |              |
 is_active  | boolean                     |           |          |                    | plain    |              |
Indexes:
    "segments_pkey" PRIMARY KEY, btree (id, app_id)
    "index_segments_on_app_id" btree (app_id)
Referenced by:
    TABLE "app_exports" CONSTRAINT "app_exports_segment_id_fkey" FOREIGN KEY (segment_id, app_id) REFERENCES segments(id, app_id)

It has a composed primary key which acts as a foreing key from another table.

cfis commented 2 years ago

Sorry, I mean defined in ActiveRecord by ruby code.

magec commented 2 years ago

Im going to close this, in the end, the reason behind was that the code I was working with had some monkeypatching on top of composite_primary_keys, mainly because it allows using 'single' primary key if there is an id field on the database. I have accommodated the thing to work after the upgrade.

cfis commented 2 years ago

Ok cool - thanks for the update.