Rails 4+ Best practices: Delete parent while keeping children - ruby-on-rails

I want to keep child records and the hierarchy, even when the parent is deleted. I see two options:
Keep the existing parent and utilize a "deleted_at" field to indicate the
parent itself is inactive, but the relationship still exists. This will lead to a number of effectively dead parent records being stored forever. Meh.
Assign all abandoned child records to a generic "collector" zombie parent record. I prefer this, but then you lose the history to the original source of the child record.
I don't have the Rails experience to see ahead as to which of these 2 would be the most advisable path to take, or maybe there's an altogether different solution.
SO is telling me this appears to be a subjective question and they may close it. I hope not, because I'm sure this is a question that others have as well.

It seems to me like you're basically asking about "soft delete" functionality. When I want this kind of behavior, I usually add an active attribute that defaults to true. I also add an active scope to the model so I can do something like Salon.active to conveniently get everything that's active.
So I guess my answer is that I'd do something like #1, which I would call a soft delete. Idea #2 seems pretty crazy to me.

Related

Rails validations: update at the same time as creation

I'm having some trouble trying to figure out how to order ActiveRecord writes to make my validations be happy, and I'm not sure what to search for this kind of problem.
The problem is that before the request would occur, everything would be valid; after the transformations would occur, everything would be valid again; but while the transformation is happening, since it's impacting more than one model instance, the database would enter an invalid state if I update each model one by one without taking into account both changes at the same time. I'd love some suggestions!
Background
I have a model called HelpRequest and another called HelperAssignments.
The rule is that a HelpRequest may have 0 or 1 active HelperAssignments. But if a Helper cannot complete the request, they may reassign it to another Helper, creating a new HelperAssignment. Since we need the history of assignments to a particular HelpRequest, there may be a number of HelperAssignments for a HelpRequest, but only one is active.
As a result, the HelperAssignment table has a few relevant attributes:
help_request_id: Refers to the HelpRequest corresponding to this assignment.
close_status: If this is set to reassigned, reassignment_id must be present.
reassignment_id: For a given help_request_id, only one may be nil (i.e. it is the current active assignment)
Problem
When a reassignment happens...
... if I create the new HelperAssignment first, it would break validations because more than one active HelperAssignment for the request would be present :(
... if I update the old HelperAssignment first to have a close_status of reassigned, the new HelperAssignment wouldn't exist yet so I couldn't get its ID, and therefore the validations would fail.
Is there an idiomatic way to do this transformation? I'd like to avoid a) disabling validations for this particular type of requests, or b) adding an extra database state for "being in the process of reassigning". Looks like enforcing referential integrity in models can get a little tricky in Rails... thanks in advance!

Prevent sql update on existing Rails model when appending to has_many relationship

According to the present Rails documentation, regarding the << operator on a has_many relationship on an existing object:
collection<<(object, …)
Adds one or more objects to the collection by setting their foreign keys
to the collection’s primary key.
(This is the interesting bit)
Note that this operation instantly fires update sql without waiting for
the save or update call on the parent object.
I didn't realize this would happen, I was quite surprised; I could have sworn this was not the case in the past, though I admit I could be wrong.
In either case, I haven't been able to find any additional documentation regarding this, however I wonder if there is a way to prevent this update?
My situation is simple, I merely have an object which exists in the database, which is being prepared for an "edit" page. I append one or multiple related objects before the page is render. C'est tout.
Update:
Apparently the same update-scenario also occurs if you set the has_many relationship directly from an array using the = operator.
Use the collection's build method. That won't immediately fire a SQL statement like the others do.
foo.bars.build(attributes)
foo.save
Lots of good information can be found here: http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html
Note: This method assumes you have the flexibility to create your objects through the build method rather than using Bar.new.

How should I go about embedding a collection of new entities in a Symfony2 Form?

I need to write a form for creating a new entity and with it, up to 3 relations (which are new entities).
I can either have it dynamically attach/delete them dynamically (which could be useful) or have all 3 always be related to the entity, and for them to have an 'active' boolean on them, which would be just as appropriate.
At what point should I be doing this? I need them rendered as checkboxes on the form.
So far I've tried attaching them to the entity prior to passing it to the form, but choice fields can't be passed unmapped entities, so that's no good.
I've also tinkered with a DataTransformer for this, although then, as far as I can see, I would have to create new entities in the DataTransformer, which seems wrong, and I can't get to work anyway- I don't have access to the entity within it and even hacking around that, the relationship fails to bind properly (Doctrine tries to save the relationships first).
In Symfony1 terms, I could just embed a couple of forms for each additional relation I needed, using new objects, and it'd just work, so surely there's still a relatively easy way around this?
A friend also recommended looking into the ResizeFormEventListener, but this, as far as I understand, is for 'resizing' a form based on the returned data, whilst I never want the form to change, I want 3 checkboxes always.
What's the best way to approach this problem?
I'm not sure on exact details without playing with it - but based on how i've done similar things, i'd be looking to use a 'collectiontype' and then adding the three department types into that.

Add file to unsaved model entity in Rails?

Is it possible to save a file in a dependent model entity when the parent (base) entity has not yet been saved?
I would like the user to be able to add images to a story prior to the story actually being saved. So my model is like this:
Story (Base Entity) has_many :pictures
+ Picture (Depedent Entity) belongs_to :story
In the Story controller, I have a separate action called add_image. However, because the instance variable #story does not seem to be persisted across requests, I cannot access it in this action.
What I have thought of doing so far is to store the #story variable in the session on create, so I can retrieve it from there. Will this work? May it have any unintended side-effects for subsequent requests? (E.g. what if I have the previous story stored in the session and add a picture to the wrong story?).
Just think about the implementation. There are two tables in the database and there should be some row story_id in the "pictures" table. What should be there, if story is not saved and it has no id yet?
Do it another way. Add some boolean flag to Stories, for example finished. Save all "unfinished" stories and change flag to "finished" on save in your application. Don't forget to regularly delete old "unfinished" (abandoned) stories and their pictures.
Apparently it is possible to save dependent records together with the main on first create:
http://api.rubyonrails.org/classes/ActiveRecord/Associations/ClassMethods.html
See the section "Unsaved objects and associations". You must use collection.build to add the dependent records.
Now my problem is still how to reliably persist the parent across requests, though I am thinking this may be possible by storing it in the session with the ID generated by mongoid (the only problem being that it is not portable across ORMs, I think).
This answers part of my question. So I will not accept any answer just yet, and once I have found a proper solution, I will give an update.

How do I sort the rows in a nested object form in rails for just one view?

When working with a nested model in a form, is there a way to sort the nested models in the view or in the controller? The closest answer I could find was here, but both of those solutions involve putting sort orders in the model. I'd rather avoid changing things fundamentally like that and keep this particular sort order to just one page.
You can always sort with ruby: parent.children.sort{|a,b| a.field <=> b.field} or something like that
Or you can add a find method to parent model, like def self.find_ordered_by_field
Can't think of another options...
Putting the sort in the models is absolutely the way to go. You shouldn't have any more ruby code than necessary in your views themselves, because it's much harder to test that your sorting is working the way you think it should.
When you add the sort at the model level (and either answer in the link you posted works well) you can add an automated test to verify that it is, in fact, sorting the way you'd like. This is business logic, and it belongs in the model.
Sometimes, however, you're looking to sort in a way that is NOT what you would normally want for this model. Maybe you normally want them sorted by name, but in this one view you want them sorted newest to oldest. At the very least, do the sort in the controller so once again it can be fully tested. But I would still put it in the model, personally.

Resources