Joe Van Dyk wrote:> 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...
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.