I'm trying my best to adhere to the thin controller/fat model
philosophy - in particular, I'm trying to make sure my validation
stays inside my models, so it can be reused in multiple places.
My current problem is that I have an action that creates several
objects all at once. In my app, there are Sources (which represent an
entire web site) and Resources (which map to a single URL). Each
Source has_many Resources (so each Resource belongs_to a Source).
In my action, I need to create both a Source and a linked Resource.
However, each has some validation that needs to occur. If either the
Source or Resource has a problem, neither should be created.
My initial thought was to use a transaction. I would use save! so that
if anything went wrong, I could just print out the error in the flash.
My controller action contained code that looked something like this:
@resource =Resource.new(:source => Source.new(:name =>
params[:name]), :url => params[:url])
@source = @resource.source
# do some stuff
rescue ActiveRecord::RecordInvalid, AssertionFailure => error
# put the error message in the flash
render :action => 'new'
If there is something wrong in Source (e.g. the name is empty), this
works fine - it prints out the nice error message I have in the Source
However, if something is wrong in the Resource, Source just gives the
following error: 'Validation failed: Resources is invalid'. That's not
very helpful to the user.
Of course, I can do @resource.save! first, but if there is a problem
with the Source, ActiveRecord complains that the source_id cannot be
null (since it could not save).
Clearly my approach is very wrong here. My goal is to
1. Only save the Source and Resource if both are valid
2. Not duplicate a bunch of validation logic in the controller
Anyone have ideas for how I can accomplish this?
Thanks in advance!