Atualização de models com paperclip
20 Aug 2015Paperclip é uma gem que facilita a integração de upload de arquivos em uma aplicação Rails. Existem vários tutoriais de como usar o Paperclip para anexar uma imagem a um model no momento da criação, mas quase nenhum que explique como manipular os anexos em caso de edição e atualização do model. Para esse exemplo usaremos as classes Exame e Arquivo.
# exame.rb
class Exame < ActiveRecord::Base
has_many :arquivos, dependent: :destroy
accepts_nested_attributes_for :arquivos
end
# arquivo.rb
class Arquivo < ActiveRecord::Base
belongs_to :exame
has_attached_file :asset,
:path => ":rails_root/storage/#{Rails.env}#{ENV['RAILS_TEST_NUMBER']}/attachments/:id/:style/:basename.:extension"
validates_with AttachmentSizeValidator, :attributes => :asset,
:less_than => 5.megabytes
do_not_validate_attachment_file_type :asset
endNo nosso exemplo, Exame tem vários Arquivos que por sua vez carrega a configuração do Paperclip. Na nossa view de edição, criaremos uma listagem dos arquivos previamente anexados, e um campo para anexar novos arquivos. Na listagem, em frente ao nome de cada arquivo, adicionaremos um checkbox que carregará a informação de qual arquivo está sendo selecionado para ser apagado:
<div class="form-group">
<%= label_tag "Arquivos já anexados", nil, class: 'col-lg-2 control-label' %>
<div class="col-lg-10">
<% if @exame.arquivos.empty? %>
Nenhum arquivo disponibilizado.
<% else %>
<table class='table table-bordered'>
<% @exame.arquivos.each do |a| %>
<tbody>
<tr>
<td><%= asset_file_name %></td>
<td>
<%= check_box_tag "delete_arquivos[]", a.id, false %>
Deletar Arquivo
</td>
</tr>
</tbody>
<% end %>
</table>
<% end %>
</div>
</div>
<div class="form-group">
<%= label_tag "Novos Arquivos", nil, class: 'col-lg-2 control-label' %>
<div class="col-lg-10">
<%= file_field_tag "assets[]", type: :file, multiple: true,
class: 'form-control' %>
</div>
</div>No controller, após passar pelas validações do Exame, checamos o params[:assets] para anexar os novos arquivos ao Exame e também checamos o params[:delete_arquivos] para deletar os arquivos selecionados. Esse parâmetro trará os ids dos selecionados.
# exames_controller.rb
def update
@exame = Exame.find(params[:id])
if @exame.update_attributes(exame_params)
if params[:assets]
params[:assets].each { |asset|
Arquivo.create asset: asset, exame_id: @exame.id
}
end
if params[:delete_arquivos]
Arquivo.destroy params[:delete_arquivos]
end
flash[:success] = 'Exame atualizado!'
redirect_to exames_url
else
render 'edit'
end
endSimples e fácil!