Skip to content

README Clarification for has_one#247

Closed
richseviora wants to merge 1 commit intonathanvda:masterfrom
richseviora:master
Closed

README Clarification for has_one#247
richseviora wants to merge 1 commit intonathanvda:masterfrom
richseviora:master

Conversation

@richseviora
Copy link

A small change to the README save others some troubleshooting time. For reasons too complicated to explain here I need to allow users to delete and create a record with a 'has_one' association.

The destruction of the associated object is expected as per has_one#association= documentation (excerpted):

Assigns the associate object, extracts the primary key, sets it as the foreign key, and saves the associate object. To avoid database inconsistencies, permanently deletes an existing associated object when assigning a new one, even if the new one isn't saved to database.

A small change to save others some troubleshooting time. For reasons too complicated to explain here I need to allow users to delete and create a record with a 'has_one' association. 

The destruction of the associated object is expected as per has_one#association= documentation (excerpt below).
 
Assigns the associate object, extracts the primary key, sets it as the foreign key, and saves the associate object. To avoid database inconsistencies, permanently deletes an existing associated object when assigning a new one, even if the new one isn't saved to database.
@nathanvda
Copy link
Owner

Are you saying the currently linked object is destroyed from the moment the view is rendered? (so when the link_to_add_association is called).

There is a simple work-around: use the :force_non_association_create option. This feels like something that used to work in rails 3, and now no longer does.

I am not sure if it is a bug in rails, as soon as the build_something is called (that is what cocoon does) the currently linked object is destroyed (because nothing is actually saved so, so you could still cancel saving). It sure does feel like a bug, if rails behaves that way, that cocoon would always delete when just rendering the view, and the user did not even express the intention to actually replace the current object.

So the current work-around is specifying that option manually, I will try to make sure I fix the code. It is not as correct to manually build the object (the association could have options which are not taken into account when manually building the object), but less worse than deleting the current object immediately 😄

@richseviora
Copy link
Author

Agreed: force_non_association_create definitely does the trick. I forgot to mention this in my PR! 😞

It was an interesting bug to chase down because I was seeing the field set rendered twice. But once I looked through the gem code it all made sense.

  Rendered journal/set_groups/_intensity_fields.html.erb (0.9ms) # Expected to render once.
   (0.1ms)  BEGIN 
  SQL (0.2ms)  DELETE FROM "intensities" WHERE "intensities"."id" = $1  [["id", 12026]]
   (7.9ms)  COMMIT
  Rendered journal/set_groups/_intensity_fields.html.erb (0.8ms) # Rendered during link_to_add_association

I think this is another argument against using has_one associations myself. I can only imagine what'd happen if there were other associations attached to the one being deleted.

@richseviora
Copy link
Author

Here's some console confirmation of the behaviour:

e = ExerciseSet.last #<ExerciseSet id: 12040...
intensity1 = e.intensity #<Intensity id: 12055...
e.build_intensity #<Intensity id: nil...
e2 = ExerciseSet.last #<ExerciseSet id: 12040...
e2.intensity #nil
Intensity.find(12055) #ActiveRecord::RecordNotFound: Couldn't find Intensity with 'id'=12055

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants