2017-04-17 5 views
1

Ich habe ein ActiveAdmin-Formular, mit dem Sie eine Youtube-URL hinzufügen können. Ich validiere diese URL in meinem Videomodell. Es funktioniert gut, wenn ich ein neues Video hinzufügen möchte, tut aber nichts, wenn ich das Video bearbeite.
app/admin/video.rb:Ruby on Rails - ActiveAdmin - Update-Modell mit virtuellem Attribut

ActiveAdmin.register Media, as: 'Videos' do  
form do |f| 
     f.inputs "Add youtube video" do 
      f.input :category 
      f.semantic_errors :error 
      f.has_many :videos, allow_destroy: true do |g| 
       g.input :mylink, :label => "Youtube link : ", :type => :text 
     end 
     actions 
     end 
    end 
end 

Modell/video.rb:

class Video < ApplicationRecord 
    belongs_to :media 
    attr_accessor :mylink 
    YT_LINK_FORMAT = /\A.*(youtu.be\/|v\/|u\/\w\/|embed\/|watch\?v=|\&v=)([^#\&\?]*).*\z/i 
    before_create :before_add_to_galerie 
    before_update :before_add_to_galerie 

    def before_add_to_galerie 
    uid = @mylink.match(YT_LINK_FORMAT) 
    self.uid = uid[2] if uid && uid[2] 
    if self.uid.to_s.length != 11 
     self.errors.add(:mylink, 'is invalid.') 
     throw :abort 
     false 
    elsif Video.where(uid: self.uid).any? 
     self.errors.add(:mylink, 'is not unique.') 
     throw :abort 
     false 
    end 
end 

validates :mylink, presence: true, format: YT_LINK_FORMAT 
end 

Es sieht aus wie die BEFORE_UPDATE Methode nie ausgelöst wird.
Wie kann ich meine Bearbeitung bearbeiten?

EDIT: Ich habe herausgefunden, dass es den before_update Link für das Media-Modell und nicht für das Video-One.Aber das Erstellen ist in Ordnung.

+0

warum es nicht ausgelöst verwenden kann? Haben Sie versucht, einen vorhandenen Datensatz zu aktualisieren? – Bohdan

+0

Ich habe gerade versucht, eine andere Methode im before_update aufzurufen, die nur etwas Text in die Konsole druckt und nichts druckt – KingOfBabu

+0

Es funktioniert, wenn ich das virtuelle Attribut nicht verwende, aber ich brauche es wirklich, um den Link zu validieren – KingOfBabu

Antwort

1

Lassen Sie mich versuchen, das Problem neu zu formulieren:

  1. Sie haben ein Modell Video
  2. Video hat ein virtuelles Attribut my_link
  3. Video ein before_update Rückruf before_add_to_galerie
  4. Sie wollen diesen Rückruf Trigger wenn nur my_link geändert wurde

sieht das korrekt aus? Wenn ja Sie 2 Möglichkeiten haben, erste - wenn Sie updated_at Änderung mit my_link entlang es haben

class Video < ApplicationRecord 
    attr_reader :my_link 
    # ... 
    def my_link=(val) 
    return val if val == my_link 
    @my_link = val 
    self.updated_at = Time.zone.now 
    end 
end 

oder Sie ActiveModel