-
Notifications
You must be signed in to change notification settings - Fork 899
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Transaction #90
Transaction #90
Conversation
This should solve all the problems with restoring associations.
Changed rollback save to save!, will raise exception when validation fails
Added delete support (add :autosave=>true to association in model)
Only mark for destruction if child still exists
…adonly" This reverts commit a694735.
@airblade did you get a chance to give this a try? Let me know if you want me to add some more tests. |
My app was being plagued by a pretty nasty bug, where when you reify a has many association, new versions were being created of the child object. Apparently "<<" calls save on the object almost automatically. I was finally able to write some tests that catch that behavior in the act. Just committed these (sorry about the dirty commit history). @egoh or @airblade if you have any idea how to fix this, I'd be pretty curious. I'm quite stumped. |
I should add, I'm usin rails 3.05. It seems that associations are handled differently in 3.1 and 2.3. |
@mike I've been really busy lately with my education and other programming work, so have no real time to put into this. I'm glad someone picks it up to try get it in the trunk release! I noticed the problem before and i have a tip for you! Another thing, the added flexibility airblade recently introduced with respect to model/tablename flexibility/extension is really nasty to extend to the whole association part. |
Thanks for the tip! I tried that a while back, but didn't have unit tests to guide me. I'll have another go at it later tonight using this approach. |
@mike That could be right, i think it had worked in some rails version (don't know which one i used back then). |
@egoh. This is pretty kludgy, but it passes the tests.
However, I'm pretty sure this will break horribly with nested has_many. But I need to write some tests for that |
@mike Like i said before, this will not work with protected attributes. |
After weighing the options, I'm not a fan of using the .build approach, since we'll always have to do a LOT of heavy lifting in order to get nested models working. The other option is to find a way to prevent << from executing a 'save' on the child. Digging in to the specifics of rails 3.0x it seems like the child is not saved if the parent object is a new record (checked with new_record?). We can fake it out by doing this
A similar approach, which would be more resilient to changes in rails, would be to intercept the DB writes, and prevent them. |
… Proposed fix for tests
…ransaction Conflicts: lib/paper_trail/has_paper_trail.rb test/dummy/db/test.sqlite3
@egoh, I'm running into the same sort of problem, but in the delete case (when the version is a 'create' event). In your original pull request you had
How was this intended to work? Wouldn't the child still be in the collection, just deleted once you save the parent? |
@mike yup, cause that was the easy way to go. The alternative better way is to really delete it from the collection, but then you need to store the childs that need to be deleted somewhere in the parent object and remove them when you safe the object. |
@egoh, @airblade. Yikes, I've found another use case that fails... thoughts on this one?
The problem is that during reify we're only appending the children that have versions after the last widget version. I wonder if there is a completely different approach to working with these association collections... |
I think I might have found a clever way to bypass a lot of this mess. AssociationProxy has a target= method which lets you set the target collection directly. The has many reify would then look something like this. Using this we can start with the pre-reified collection, make changes to it based on the versions, then set it as the collection on the reified object.
|
dd4280e
to
a683be8
Compare
This fork is 99% the work of @egoh, I just added some unit tests for the has_many and fixed a few minor bugs. A few things to note:
Because the default behavior of the tests is to run everything inside the setup block as a single transaction, a lot of the reify association stuff was breaking (since it depends on transaction IDs). This was addressed before by using the method "make_last_version_earlier", I tried using the same kind of hack, but couldn't get it to work. Ultimately I just turned off the transactional fixtures.
I question how the reify_has_manys and reify_has_ones handled the create event. It seemed to me like they should have set child equal to nil (line 172 and 200 of version.rb), but if I'm missing something then please correct.
I had to make some of the inheritance column tests more explicit since the transactional fixtures was turned off.
I only wrote some very basic tests for has_many, but now that they're passing it should be easier to write some more.