Adding to errors in controller?

def update
@product = Product.find(params[:id])
@product.attributes = params[:product]
if params[:main_image]
image = Image.new params[:main_image]
if image.save
@product.main_image.destroy if @product.main_image
@product.main_image = image
else
@product.errors.add_to_base(image.errors.full_messages.join(",
"))
end
end

if @product.errors.empty? and @product.save
  flash[:notice] = "Product was successfully updated"
  redirect_to :action => "show", :id => @product
else
  render :action => 'edit'
end

end

Currently, products belong_to images, but later, I’ll probably have
products has_many images.

Say an image is invalid. So it won’t be saved. How do I properly
show that to the user? The above is my approach, where I have to
manually add image.errors.full_messages to the product.errors. But
then, I noticed that when an image had an error (and the error text
was added to product.errors), product still happily saved itself. So
that’s why there’s a check in there for product.errors.empty?.

I know there’a better way to do this that I’m missing…

Joe Van D. wrote:

  end

Currently, products belong_to images, but later, I’ll probably have
products has_many images.

Say an image is invalid. So it won’t be saved. How do I properly
show that to the user? The above is my approach, where I have to
manually add image.errors.full_messages to the product.errors. But
then, I noticed that when an image had an error (and the error text
was added to product.errors), product still happily saved itself. So
that’s why there’s a check in there for product.errors.empty?.

I know there’a better way to do this that I’m missing…

Calling save (or valid?) resets an object’s errors. So your best
bet would be to add a “validates_associated :main_image” to the Product
model. Then just save @product in your controller, which if valid
will automatically also save any new (un-saved) associated image.

This will also ensure that a valid new product image doesn’t get
saved if other parts of the product are invalid.

Prior to assigning the new image to the product, hold any old image
object in a variable so you can destroy it if the product save is
successful. You may be able to automate this in the model by
adding an attr_accessor called “new_main_image”, and using this
instead of “main_image” in your view form.


We develop, watch us RoR, in numbers too big to ignore.