Validate() with has_many association


#1

I’m creating a simple portfolio site for a painter. I have a painting
and an image model with following relationship:

Painting
has_many :images

Image
belongs_to :painting

On the edit screen the user can edit the Painting data as well as upload
pictures for a thumbnails and full size image. The Image model extracts
filename, width, and height from the uploaded file, saves those to the
database and saves the uploaded file to disk. For the Image I’m doing
some custom validation so I’ve overridden validate().
My problem is that, though Image is correctly validating, a failed
validation is not propigating up to the Painting. If Image is invalid,
it is not saved but Painting is and none of the errors are propigated
back to the view. My assumption is that the Painting would look for
errors in the images array and not save if one was found. It looks like
that assumption is wrong.
Can any one tell me how validation works with a has_many
relationship? Can anyone suggest a technique for making this work?

Here’s hopefully the relevant parts of the code:

Admin Controller
def update

straight forward update of the attributes

if @painting.update_attributes(params[:painting])
flash[:notice] = @painting.name + ’ was successfully updated.’
# User has the choice to save and redisplay the screen
# Or save and go to the next Painting
if params[:commit] == ‘Save’
redirect_to :action => ‘edit’, :id => @params[:id]
else
redirect_to :action => ‘edit’, :id => @next_painting_id
end
else
#there was a problem updating the record
@heading = “Painting Editor”
render :action => ‘edit’, :id => @params[:id]
end
end

painting model
has_many :images

def thumbnail=(uploaded_image)

form has a file upload field named painting[:thumbnail]

add_image_by_size(uploaded_image, THUMBNAIL)
end

private
def add_image_by_size(file, image_size)
if existing_image = get_image_by_size(image_size) then
if existing_image.uploaded_file?(file, image_size)
existing_image.save
else
#handle the fact that it didn’t save
end
else
# a new image is being associated with the painting
image = Image.new
image.uploaded_file(file, image_size)
self.images << image
end
end

image model
belongs_to :painting

def validate

this validates fine but the error is not being acted upon by the

painting

nor is it being displayed to the user

if self.size == THUMBNAIL then
unless self.width == DIMENSIONS[:thumbnail][:width] then #
simplified
errors.add_to_base(“Thumbnails must by #{DIMENSIONS
[:thumbnail][:width]} by #{DIMENSIONS[:thumbnail][:height]} pixels.”)
end
end
end

Thank you,
William


#2

Hi,

I am not sure, but perhaps this is a situation where one would use
validates_associated?

Sean