I am using paperclip in a Rails 3.0.5 application.
I have the following models:
1
2
3
4
5
6
7
8
class Ad < ActiveRecord : :Base
belongs_to :category
has_many :images , :dependent => :destroy
accepts_nested_attributes_for :images ,
:reject_if => lambda { | attr | attr [ :image ]. blank? },
:allow_destroy => true
. . .
end
Every ad has many images. I manage images through paperclip gem. Here the model for Image:
1
2
3
4
5
6
7
8
9
10
11
12
class Image < ActiveRecord : :Base
belongs_to :ad
has_attached_file :image ,
:styles => { :thumb => "100x100>" , :medium => "600x600>" }
validates_attachment_size :image ,
:less_than => 1 . megabyte
validates_attachment_content_type :image ,
:content_type => [ 'image/jpeg' , 'image/png' , 'image/gif' ]
. . .
end
The form for ad has a fields_for images. The standard update action in the ads controller should look like this:
1
2
3
4
5
6
7
8
9
10
11
12
class AdsController < ApplicationController
. . .
def update
@ad = Ad . find ( params [ :id ] )
if @ad . update_attributes ( params [ :ad ] )
redirect_to ad_path ( @ad ), :notice => t ( :ad_update_ok )
else
render 'edit'
end
end
. . .
end
Unfortunately this doesn’t work because of a bug in this version of Rails. The update action updates the ad but doesn’t remove the related images if the _destroy
attribute of the params
hash is true.
After 2 hours of debugging and googling, I found a workaround to the problem. The solution is to add an “includes(:images)” method call before the find call inside the update action like shown below:
1
2
3
4
5
6
7
8
9
10
11
12
class AdsController < ApplicationController
. . .
def update
@ad = Ad . includes ( :images ) . find ( params [ :id ] )
if @ad . update_attributes ( params [ :ad ] )
redirect_to ad_path ( @ad ), :notice => t ( :ad_update_ok )
else
render 'edit'
end
end
. . .
end
Hope this helps.