Raylar Ataç eki nasıl silinir?


84

Ben kullanıyorum Paperclip Raylar 3. Mevcut bir eki silmek istiyor (/ Amazon s3 w) it değiştirmeden bir güncelleme eylemini kullanarak.

Sadece bu bir örnek buldum burada ve işe, sadece silme olmaz alamadım ve neden söylemek günlüklerinde hiçbir şey yoktu. Formda şöyle bir şey yapmak istedim:

<%- unless @page.new_record? || !@page.image? -%>
    <%= f.check_box :image_delete, :label => 'Delete Image' %>
<%- end -%>

(sayfa modelin adıdır, resim eki tutan öznitelik adıdır)

Ancak bu onay kutusunu nasıl tespit ederim ve daha da önemlisi, resmi nasıl silerim? Herhangi bir yardım için minnettarım!

Yanıtlar:


104

İlk olarak, form_for'da bir onay kutusu oluşturduğunuzda (ki bu size benziyor), o zaman form varsayılan olarak göndermelidir: image_delete işaretliyse "1" ve işaretli değilse "0" olarak. Yöntem bildirimi şuna benzer:

def check_box(method, options = {}, checked_value = "1", unchecked_value = "0")

Bu, isterseniz başka değerler atayabileceğinizi gösterir, ancak bu elbette isteğe bağlıdır.

İkinci olarak, bir eki, eklendiği model örneğini silmeden manuel olarak silme çağrısı şudur:

@page.image.destroy #Will remove the attachment and save the model
@page.image.clear #Will queue the attachment to be deleted

Resimleri bir onay kutusu aracılığıyla silme yönteminizi gerçekleştirmek için, belki Sayfa modelinize şuna benzer bir şey ekleyebilirsiniz:

class Page < ActiveRecord::Base
  has_attached_file :image

  before_save :destroy_image?

  def image_delete
    @image_delete ||= "0"
  end

  def image_delete=(value)
    @image_delete = value
  end

private
  def destroy_image?
    self.image.clear if @image_delete == "1"
  end
end

Bu şekilde, formunuzu oluşturduğunuzda ve: image_delete onay kutusunu eklediğinizde, Kullanıcı örneğinden "0" varsayılan değerini yükleyecektir. Ve bu alan işaretlenirse, denetleyici image_delete'i "1" olarak günceller ve Kullanıcı kaydedildiğinde görüntünün silinip silinmeyeceğini kontrol eder.


Bu örnekte, Sayfa # resmi başka bir modele mi atıfta bulunuyor has_attached_file, yoksa Sayfa eki olan, image adında mı?
John Bachir

@page has_attached_file: image model değişkenidir, ancak bazı nedenlerden dolayı modele Kullanıcı adını verdim. Açıklığa kavuşturmak için değiştirip güncelleyeceğim.
DanneManne

Tamam, bu daha mantıklı :)
John Bachir

Neden orada self.image.destroy yapmadığınızı anlamıyorum - temeldeki dosyayı kaldırıp Sayfa modelindeki resimle ilgili meta bilgileri koruyor mu? Bunu neden yapmak istersiniz? (ve soruyu soranın yapmak istediği şey bu gibi görünmüyor)
John Bachir

11
Bu yaklaşım benim için de işe yaradı ... ancak bir sorunla karşılaştım ... kullanıcı image_delete onay kutusunu işaretlerse ve aynı zamanda formda yeni bir resim eklerse, eski resim silinir ve yeni resim kaydedilmez . Ben durumu değiştirerek bu çözüldü self.image.clear if @image_delete == "1" and !image.dirty?içinde destroy_image?yöntemle
Zeeshan

97

has_attached_file :asset

=>

    attr_accessor :delete_asset
    before_validation { asset.clear if delete_asset == '1' }

Varlığı yok etmeye gerek yok, Paperclip bunu yapacak.

Formda form.check_box(:delete_asset)yeterli olacaktır.


3
Bu işe yarıyor ve @DanneManne'nin IMHO yanıtından daha basit. Çok iyi! :)
MetalElf0

Bunun için nasıl bir şartname yazarsınız?
Hengjie

1
Teşekkürler ! Bunu daha has_attached_file :asset has_destroyable_file :asset da config/initializers/ azaltmama
Sunny

2
En azından accepts_nested_attributes aracılığıyla bu yöntemle ilgili bir sorun buldum. başka öznitelikler değiştirilmediyse, yuvalanmış bir kaydetme işleminde before_validation tetiklenmez. Çözüm için aşağıdaki
Paul Odeon

4
@SurgePedroza: delete_asset
sman591

12

Bu Benoit'in cevabıdır, ancak bir modüle sarılmıştır ve modelde değiştirilen tek şeyin yok etme onay kutusunun olduğu yuvalanmış öznitelik modellerinin uç durumunu kapsar.

Modeldeki tüm ataşmanlara uygulanacaktır.

# This needs to be included after all has_attached_file statements in a class
module DeletableAttachment
  extend ActiveSupport::Concern

  included do
    attachment_definitions.keys.each do |name|

      attr_accessor :"delete_#{name}"

      before_validation { send(name).clear if send("delete_#{name}") == '1' }

      define_method :"delete_#{name}=" do |value|
        instance_variable_set :"@delete_#{name}", value
        send("#{name}_file_name_will_change!")
      end

    end
  end

end

1
Bunun neden daha fazla dikkat çekmediğini bilmiyorum. attachment_definitionssadece hayatımı kurtardım.
tamam

Yine de bu satıra da ihtiyaç var:attr_accessible :"delete_#{name}"
okay56k

2
Yukarıdaki örnek, endişelerinizde veya model klasörünüzde olmalıdır. İstediğiniz modelde sadece çizgiyi ekleyininclude DeletableAttachment herhangi bir has_attached_fileifadenin altındaki
Paul Odeon

2
Rails3'te attr_accessible'a ihtiyacınız olacak: "_ # {isim}" i de sil
Mateu

1
:delete_<your_attribute>Denetleyicinizde güçlü parametreler kullanıyorsanız izin vermeyi unutmayın
ivanxuu

5

bunu da Sayfa modelinize eklemeyi unutmayın:

attr_accessible :image_delete

1

Paul'ün çözümünün Rails 5 özel özelliğini desteklemek için değiştirilmiş versiyonu. Keşke modülü has_attached_filetanımlardan önce dosyanın en üstüne eklemenin bir yolu olsaydı .

module Mixins
  module PaperclipRemover

    extend ActiveSupport::Concern

    included do
      attachment_definitions.keys.each do |name|

        attribute :"remove_#{name}", :boolean

        before_validation do
          self.send("#{name}=", nil) if send("remove_#{name}?")
        end

      end
    end

  end

end

0

Bunu daha az kodla, sadece delete_attachmentmodel tarafına bir uygulayarak başardı . :

class MyModel < ApplicationRecord
  has_attached_file :image

  def image_delete=(other)
    self.image = nil if other == "1" or other == true
  end
end
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.