I can't duplicate this finding here. Here's the console log:
2.4.2 :001 > p = Person.new name: 'Walter'
=> #<Person id: nil, name: "Walter", created_at: nil, updated_at: nil>
2.4.2 :002 > p.save
(0.2ms) begin transaction
SQL (2.8ms) INSERT INTO "people" ("name", "created_at", "updated_at") VALUES (?, ?, ?) [["name", "Walter"], ["created_at", "2018-02-04 21:47:31.000973"], ["updated_at", "2018-02-04 21:47:31.000973"]]
(1.3ms) commit transaction
=> true
2.4.2 :003 > c = Picture.new file: 'some file'
=> #<Picture id: nil, file: "some file", created_at: nil, updated_at: nil>
2.4.2 :004 > c.save
(0.2ms) begin transaction
SQL (2.2ms) INSERT INTO "pictures" ("file", "created_at", "updated_at") VALUES (?, ?, ?) [["file", "some file"], ["created_at", "2018-02-04 21:47:54.717609"], ["updated_at", "2018-02-04 21:47:54.717609"]]
(1.4ms) commit transaction
=> true
2.4.2 :005 > p.pictures << c
(0.1ms) begin transaction
SQL (0.6ms) INSERT INTO "person_pictures" ("person_id", "picture_id", "created_at", "updated_at") VALUES (?, ?, ?, ?) [["person_id", 1], ["picture_id", 1], ["created_at", "2018-02-04 21:47:58.847298"], ["updated_at", "2018-02-04 21:47:58.847298"]]
(1.1ms) commit transaction
Picture Load (0.4ms) SELECT "pictures".* FROM "pictures" INNER JOIN "person_pictures" ON "pictures"."id" = "person_pictures"."picture_id" WHERE "person_pictures"."person_id" = ? LIMIT ? [["person_id", 1], ["LIMIT", 11]]
=> #<ActiveRecord::Associations::CollectionProxy [#<Picture id: 1, file: "some file", created_at: "2018-02-04 21:47:54", updated_at: "2018-02-04 21:47:54">]>
2.4.2 :006 >
Here's the models:
class Picture < ApplicationRecord
has_many :person_pictures
has_many :people, through: :person_pictures
end
class Person < ApplicationRecord
has_many :person_pictures
has_many :pictures, through: :person_pictures
end
class PersonPicture < ApplicationRecord
belongs_to :person
belongs_to :picture
end
Whatever is happening on your app is not clear, but you can see that after you save the person and the picture, when you add that saved picture to the saved person's 'pictures' collection, the only record that gets created is a person_picture. Now if either the person or the picture was in the "new" state, that is to say, not saved yet, then I could imagine that it would be saved by ActiveRecord first in order to allow the person_picture record to be saved. Both IDs have to be known before the join object can be saved.
Walter