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