Forum: Ruby on Rails validate() with has_many association

Announcement (2017-05-07): www.ruby-forum.com is now read-only since I unfortunately do not have the time to support and maintain the forum any more. Please see rubyonrails.org/community and ruby-lang.org/en/community for other Rails- und Ruby-related community platforms.
C56f6508ce4610e8527606a435b5870f?d=identicon&s=25 William Lefevre (wlefevre)
on 2006-02-17 19:25
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
9dbe5b9021bf8477a3b7e747b44bde48?d=identicon&s=25 Sean O'Hara (Guest)
on 2006-02-17 22:36
(Received via mailing list)
Hi,

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

Sean
This topic is locked and can not be replied to.