DEV Community

tomdonarski
tomdonarski

Posted on

Wait, what? PK is not needed for HABTM?

While skimming over Rails’ docs I’ve found a sentence about HABTM (has_and_belongs_to_many) association that tickled my interest:

(…) For has_and_belongs_to_many associations, you'll need to create a join table without a primary key.

It made my mind go blank for a moment, and I started to wonder "Hey, can a table do not have a primary key?"

👉 Yes, it's possible. Primary key is just a constraint (source).

Then I went on to inspect an immediate project to see if there’s any join table for HABTM association, and saw this:

CREATE TABLE public.organizations_vendors (
    id integer NOT NULL,
    organization_id integer,
    vendor_id integer
);
Enter fullscreen mode Exit fullscreen mode

I started digging, and found that the HABTM join table is an implementation detail, not a real model. Which is also hinted by Rails’ docs:

You'd use has_and_belongs_to_many when:

  • The association is simple and does not require additional attributes or behaviors on the join table.
  • You do not need validations, callbacks, or extra methods on the join table.

It turns out PK on a HABTM join table is not required, as functionally it’s irrelevant.

If it is (application-wise) - then most likely has_many :through would be a better choice (source).

You'd use has_many :through when:

  • You need to add extra attributes or methods to the join table.
  • You require validations or callbacks on the join model.
  • The join table should be treated as an independent entity with its own behavior.

Top comments (0)