Ruby on Rails Thursday, January 29, 2015

Posted this to Stack Overflow yesterday and received no replies, so i figured I would try here.

I am working on a Rails app that has lots of data in many different tables related to each other via :has_many through associations. The problem here is that these associations are not static, like your typical Post - User, Assembly - Part, Book - Author associations that never change. Associations in my app will change all the time. The objective is to find the most efficient way to manage associations between existing objects in the database.

As I've recently discovered, Rails does not automatically create associations between existing objects and nested forms are only usable when associations already exist.

For example, I have a form that loads a Contact from contacts table. Same form has a Commandmulti-select populated from commands table. I want to associate multiple commands with this Contact, so i select few commands in my multi-select, which adds them to an array of hashes called notification_commands. Since Rails does not do automatic association, I have to do something like this:

contact = Contact.find_by_id params[:id]  commands = params[:contact][:notification_commands].collect { |c| c[:id] }  contact.commands << Command.find(commands)

This works OK... unless, lets say, I want to associate another command with this contact. In that case existing association records end up getting duplicated and new one added. Ok, I can do unique validations in my model... or I can just use brute force, destroy all associations and re-establish them again.

contact = Contact.find_by_id params[:id]  commands = params[:contact][:notification_commands].collect { |c| c[:id] }  contact.commands.destroy_all  contact.commands << Command.find(commands)

Ok. Thats not really all that elegant...

Model validations sound like a good option here and I will put them in as an extra safety measure, but why make the application do extra work? Duplicate records should be discarded before they even get to the model.

Another possibility (that I know of) is to compare arrays in my controller and see what the difference is between data in the db and what's being posted from the form.

Now, my views are AngularJS, and I am yet to figure out how to make Angular use Rails _destroy method. If that's not possible, I would have to do another array comparison, now in reverse, to see what associations need to be removed. Again, not very elegant.

So, while the brute force method of destroying all associations and re-establishing them all again works and requires the least amount of code, I don't feel that it is good practice.

Any suggestions on what is the more efficient and cleanest way to manage associations between multiple existing objects?

--
You received this message because you are subscribed to the Google Groups "Ruby on Rails: Talk" group.
To unsubscribe from this group and stop receiving emails from it, send an email to rubyonrails-talk+unsubscribe@googlegroups.com.
To post to this group, send email to rubyonrails-talk@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/rubyonrails-talk/a19b1902-1bdc-408f-a06c-dd6f41fcbd96%40googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

No comments:

Post a Comment