आसक्ति को कैसे हटाएं


84

मैं रेल 3. पर पेपरक्लिप (w / Amazon s3) का उपयोग कर रहा हूं। मैं अपडेट कार्रवाई का उपयोग किए बिना मौजूदा अनुलग्नक को हटाना चाहता हूं ।

मुझे इसका केवल एक उदाहरण यहां मिला है और यह काम करने के लिए नहीं मिल सकता है, यह बस नहीं हटेगा और लॉग इन करने के लिए कुछ भी नहीं कहना चाहिए। मैं फार्म पर कुछ इस तरह करना चाहता था:

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

(पेज मॉडल का नाम है, छवि विशेषता नाम है जो लगाव रखता है)

लेकिन मैं उस चेकबॉक्स और अधिक महत्वपूर्ण बात का कैसे पता लगाऊं, मैं छवि को कैसे हटाऊं? मैं किसी भी मदद की सराहना करता हूं!

जवाबों:


104

सबसे पहले, जब आप एक form_for में check_box बनाते हैं (जो ऐसा दिखता है कि आप हैं), तो फ़ॉर्म को डिफ़ॉल्ट रूप से भेजना चाहिए: image_delete को "1" के रूप में यदि चेक किया गया हो और यदि अनियंत्रित हो तो "0"। विधि घोषणा इस तरह दिखती है:

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

जो यह दर्शाता है कि यदि आप चाहें, तो आप अन्य मान निर्दिष्ट कर सकते हैं, लेकिन यह वैकल्पिक है।

दूसरे, जिस मॉडल से यह जुड़ा है उसे हटाए बिना अटैचमेंट को मैन्युअल रूप से डिलीट करने के लिए कॉल:

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

और चेकबॉक्स के माध्यम से छवियों को हटाने के अपने तरीके को पूरा करने के लिए, शायद अपने पेज मॉडल में ऐसा कुछ जोड़ें:

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

इस तरह, जब आप अपना फ़ॉर्म बनाते हैं और: image_delete चेकबॉक्स जोड़ते हैं, तो यह उपयोगकर्ता के उदाहरण से डिफ़ॉल्ट मान "0" को लोड करेगा। और यदि उस फ़ील्ड की जाँच की जाती है, तो कंट्रोलर image_delete को "1" में अपडेट कर देगा और जब यूजर सेव हो जाएगा, तो यह चेक करेगा कि इमेज डिलीट करनी है या नहीं।


इस उदाहरण में, क्या पृष्ठ # छवि किसी अन्य मॉडल को संदर्भित has_attached_fileकरता है, या क्या पृष्ठ का अनुलग्नक, नाम वाली छवि है?
जॉन बाचिर

@page मॉडल वैरिएबल है जिसमें has_attached_file: छवि है, लेकिन मुझे लगता है कि किसी कारण के लिए उपयोगकर्ता का नाम मॉडल है। मैं बदलूंगा और स्पष्ट करने के लिए अपडेट करूंगा।
डेननेन

ठीक है, यह अधिक समझ में आता है :)
जॉन बाचिर

मुझे समझ नहीं आ रहा है कि आप सिर्फ self.image.destroy क्यों नहीं करते हैं - स्पष्ट रूप से अंतर्निहित फ़ाइल को हटा देता है, लेकिन पेज मॉडल में छवि के बारे में मेटा जानकारी बनाए रखता है? तुमने ऐसा क्यों करना चाहोगे? (और ऐसा नहीं लगता है कि प्रश्न पूछने वाला क्या करना चाहता है)
जॉन बाचिर

11
इस दृष्टिकोण ने भी मेरे लिए काम किया ... लेकिन मुझे एक समस्या का सामना करना पड़ा ... यदि उपयोगकर्ता image_delete चेकबॉक्स की जांच करता है और फॉर्म में एक ही समय में एक नई छवि भी जोड़ता है, तो पुरानी छवि हटा दी जाती है और नई छवि सहेजी नहीं जाती है । मैंने इस स्थिति को विधि self.image.clear if @image_delete == "1" and !image.dirty?में बदलकर इसे हल कियाdestroy_image?
जीशान

97

has_attached_file :asset

=>

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

परिसंपत्ति को नष्ट करने की आवश्यकता नहीं है, पेपरक्लिप करेगा।

रूप form.check_box(:delete_asset)में पर्याप्त होगा।


3
यह काम करता है और यह @DanneManne उत्तर IMHO की तुलना में सरल है। बहुत अच्छा! :)
MetalElf0

आप इसके लिए एक युक्ति कैसे लिखेंगे?
हेंजी

1
धन्यवाद ! मुझे इसे और भी कम करने में मदद करने के लिए: has_attached_file :asset has_destroyable_file :asset मैंने config/initializers/ gist.github.com/3954054
सनी

2
मुझे कम से कम एक्सीडेंट_नएस्टेड_एट्यूएंट्स के माध्यम से इस पद्धति की समस्या मिली। इससे पहले कि अगर कोई अन्य विशेषताओं में बदलाव नहीं किया गया है, तो नेस्टेड सेव पर ट्रिगर नहीं होगा। समाधान के लिए मेरा जवाब नीचे देखें
पॉल ओडोन

4
@SurgePedroza मेरा मानना ​​है कि आपको पैरामीटर को अनुमति देने की आवश्यकता है: Delete_asset, guide.rubyonrails.org/…
sman591

12

यह बेनोइट का जवाब है, लेकिन एक मॉड्यूल में लिपटे हुए हैं, और नेस्टेड विशेषता मॉडल के किनारे के मामले को कवर करते हैं जहां नष्ट होने वाला टिकबॉक्स मॉडल पर केवल एक चीज है जिसे बदल दिया गया है।

यह मॉडल पर सभी अनुलग्नकों पर लागू होगा।

# 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
पता नहीं क्यों यह अधिक ध्यान नहीं दिया है। attachment_definitionsबस मेरी जान बचाई।
OK56k

हालांकि इस लाइन की जरूरत है:attr_accessible :"delete_#{name}"
OK56k

2
ऊपर का उदाहरण आपकी चिंताओं या मॉडल फ़ोल्डर में होना चाहिए। मॉडल में जहां आप चाहते हैं कि वह बस include DeletableAttachmentकिसी भी has_attached_fileबयान के नीचे की रेखा को जोड़ दे
पॉल ओडोन

2
Rails3 में आपको attr_accessible की आवश्यकता होगी: "Delete _ # {name}" भी
Mateu

1
:delete_<your_attribute>यदि आप अपने नियंत्रक में मजबूत मापदंडों का उपयोग कर रहे हैं तो अनुमति देना याद रखें
ivanxuu


1

पॉल के समाधान का संशोधित संस्करण, रेल 5 कस्टम विशेषताओं का समर्थन करने के लिए। मैं बस चाहता हूं कि has_attached_fileपरिभाषाओं से पहले, फ़ाइल के शीर्ष पर मॉड्यूल को शामिल करने का एक तरीका हो ।

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

कम कोड के साथ इसे प्राप्त करने में सक्षम था, बस delete_attachmentमॉडल के पक्ष में लागू करने से :

class MyModel < ApplicationRecord
  has_attached_file :image

  def image_delete=(other)
    self.image = nil if other == "1" or other == true
  end
end
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.