开发者

Paperclip, multiple attachments and validation

Does anybody have a Rails 3 example of multiple attachments working with validation on a multipart form? I've been trying to get this working forever (and have found every blog post and message I开发者_如何学编程 could, but none cover this situation, and the docs don't help at all).

The first problem is that most examples use 'new_record?' in the view template, but this always returns true in a new/create sequence when validation fails because no model instances have been saved (so no 'id' value). So if you start with 5 model instances/file inputs and upload one file, you now have 6 file inputs presented when you re-render the new view, and the 'unless' clause fails for the same reason and no thumbnails are presented.

I want to preserve the link to the uploaded file (and I know this is possible--they're living in a temp directory) while presenting validation errors to the user for other required fields.

Somebody somewhere must have this working with Paperclip. ;)


The way I'm using:

I have properties that has many photos (10 in case). Going to the code whe have:

In properties controller:

 def new
    @search = Property.search(params[:search])
    @property = Property.new
    10.times { @property.photos.build }    

    respond_to do |format|
      format.html # new.html.erb
      format.xml  { render :xml => @property }
    end
  end

  # GET /properties/1/edit
  def edit
    @search = Property.search(params[:search])
    @property = Property.find(params[:id])

    # Se o usuário atual for dono da propriedade
    if current_user.id == @property.user_id
        @photos = Photo.where("property_id = ?", @property.id)
        @N = @photos.count
        @N = 10-@N      
        @N.times { @property.photos.build }
    else
        render :action => "show"
    end

  end

10.times "render" 10 times the photo field in view. When in edit form, just apper photo fields lefting. For exemple: At 1st time I uploaded 3 photos, then if I want to upload more, just 7 fields appear.


In property model I have:

class Property < ActiveRecord::Base
    attr_accessible :photos_attributes, :logradouro, :complemento, :wc, :negocio, :cep, :vagas, :valor, 
    :quartos, :uf, :area, :bairro, :suites, :salas, :numero, :cidade, :descricao,
    :status, :tipoImovel
    has_many :photos
    accepts_nested_attributes_for :photos, :allow_destroy => true

end

This allow photos to be uploaded.


Photo model:

class Photo < ActiveRecord::Base
  belongs_to :property    

  has_attached_file :photo, :styles => { :small => "100x100>", :medium => "530>x530", :large => "800x800>" }
  validates_attachment_presence :photo
  validates_attachment_size :photo, :less_than => 500.kilobytes
end

In my form partial:

<div id="new_up">            
            <%= f.fields_for :photos do |p| %>
                <% if p.object.new_record? %>
                    <p><%= p.file_field :photo %>
                       <%= p.radio_button :miniatura, true -%>
                    </p>
                    <% end %>
            <% end %>
          </div>

         <div id="old_up">
            <h4>Imagens Atuais</h4>
            <% f.fields_for :photos do |p| %>   
                <% unless p.object.new_record? %>   
                    <div style="float: left;">
                        <%= p.radio_button :miniatura, true -%>
                        <%= link_to image_tag(p.object.photo.url(:small)), p.object.photo.url(:original) %>
                        <%= p.check_box :_destroy %>            
                    </div>  
                <% end %>
           <% end %>
         </div>


The answer I went with is to use carrierwave instead of paperclip. It only took me about an hour to cut over, and it solves this problem out of the box.

Here's my answer in another thread with much more detail: Not losing paperclip attachment when model cannot be saved due to validation error


You could achieve this by using three models, and a bit of controller magic.

The first model is the model you actually want. Let's say Biography.

class Biography < ActiveRecord::Base
  has_one :biography_fields
  has_many :biography_attachments
end

class BiographyFields < ActiveRecord::Base
  belongs_to :biography

  # Validations
end

class BiographyAttachment < ActiveRecord::Base
  belongs_to :biography

  # Paperclip stuff
end

Now in your controller you can do something like this:

class BiographiesController

  def some_method
    @biography = Biography.find(params[:biography_id]) || Biography.create!

    if @biography.biography_data.create(params[:biography_data])
      # Try to save the uploads, if it all works, redirect.
    else
      # Still try the uploads, if they work, save them and make sure to pass the :biography_id as a hidden field so they can be used without re-uploading. Also reflect this in the form.
    end
  end

end
0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜