I just had an app trip over this https://rails.lighthouseapp.com/projects/8994-ruby-on-rails/tickets/634
A quick look into habtm and hmt in associations/ shows that they do
have insert_record defaulting to `force = true` whereas has_many has
it defaulting to false. I'm not sure whether there's some reason in a
bigger picture than I'm looking at for this to exist as is.
Like does it have to be an exception to roll-out the changes to the
join tables or something?
Calling create on the has_many :through association necessarily
involves creating both the through record, and the target. Tagging
and Tag f.ex. So we can't actually return the 'tag' until we have
created and persisted the tagging object. otherwise foo.tags and
foo.taggings.map(&:tag) will be inconsistent and without a rollback
the DB will be full of nonsense records. There's also the issue of
saving the tag, then the tagging, which order do you do it in etc.
By doing it with save! and a transaction, everything gets cleaned up nicely.
However raising the exception from create *is* kinda counter intuitive
and could lead to code generating exceptions in production after
running fine for ages. I think the better option would be:
# revisit the restriction we've placed here and make sure it still
# if it does, deprecate calling .create on those associations, and
make .create! the only option
# if it doesn't, change the code.
So either, everything will work as expected, or you'll always get an
error. This will at least stop surprising people.