2011-02-28 13 views
11

Bir RoR uygulamasında, modellerimden birinde ActiveRecord'un update_attributes() yöntemini uzmanlaşmak ve özel işlemlerin bazı özniteliklerini ayıklamak ve geri kalanını orijinal update_attributes() yöntemine aktarmak istiyorum. ayrıntıları:Ruby/RoR: Orijinal metodu super() ile mi çağırıyorsunuz?

undefined method `update_attributes' for true:TrueClass 

... benim gerçekten Ruby süper anahtar kelimeyi anlamıyorum şüpheli yapar:

class Premise < ActiveRecord::Base 
    ... 
    def update_attributes(attrs) 
    attrs.each_pair do |key, val| 
     unless has_attribute?(key) 
     do_special_processing(key, val) 
     attrs.delete(key) 
     end 
    end 
    # use original update_attributes() to process non-special pairs 
    super.update_attributes(attrs) 
    end 
    ... 
end 

super.update_attributes (öznitelik) çağrısı bir hata yükseltir. Neyi kaçırıyorum? Özellikle, orijinal update_attributes() yöntemini nasıl arayabilirim?

cevap

15

Sen istiyorum: buna bir argüman olarak attrs geçen orijinal bir yöntem arayacak

super(attrs) 

.

Artık, asıl update_attributes tarafından döndürülen "true" değerinde update_attributes öğesini çağırmaya çalışıyorsunuz. ... Yakut süper yılında

def update_attributes_with_special(attrs) 
    attrs.each_pair do |key, val| 
    unless has_attribute?(key) 
     do_special_processing(key, val) 
     attrs.delete(key) 
    end 
    end 
    update_attributes_without_special(attrs) 
end 
alias_method_chain :update_attributes, :special 
+4

Bu durumda, 'update_attributes (attrs)' ve 'super (attrs)' üzerindeki argümanlar aynıdır. Parantez olmadan "süper" diyebilirsiniz. –

+0

@LBg Ah, teşekkürler, iyi bir nokta. Bununla ilgili cevabımın sonunda da biraz düzeltdim; Orijinal olarak, sorudaki kodun argüman içermeyen update_attributes adlı olduğunu yazmıştım, ancak bu doğru değil. – DSimon

+0

Bingo - teşekkürler. Bir java programcısı olarak geçmişim geçiyor ... –

4

Bu alias_method_chain için daha iyi bir kullanım benziyor Bir alt sınıf, süper sınıfı (veya üst sınıfı tanımlamazsa ataları) aynı yöntemi, alt sınıf yöntemine geçirilen tüm parametrelerle çağırır. Yani, burada, sadece süper yazabilirdin. super() çağrılması

o parametrelerinin geçen herhangi bir parametre olmadan üst sınıf (veya ataları) yöntemini

(... Bu yöntemi herhangi bir parametre kabul varsayarak) parametrelerin herhangi bir kombinasyonu ile üst sınıf yöntemini super(...) aramaları çağrılması çağırır

+0

Bunu düşündüm. Bu bir sonraki soruya yalvarır: ne zaman alt sınıfta olursunuz ve ne zaman zincirlenirsiniz? –

+0

@FearlessFool: Miras genellikle Ruby'de paylaşılan iç devlet/kaynaklar için zorlayıcı bir argüman olmadan bir kod kokusu. Alias_method zincirini kullanmanın yararı pastanızı yiyor ve buna sahip olmak. Değiştirilmiş bir update_attributes() ile bir sınıf elde edersiniz ve değiştirilmemiş işlevselliği de korursunuz. – Winfield

35

olan parantez önemi yok özel bir durum bir yöntemde parametresi (ne de parantez) olmadan super çağrılması

:

+0

Bu adam çok kullanışlıdır. Açıkça alınan aynı parametreleri göndermek nasıl ve yöntem yöntem (param, * otherargs) 'dir? – unmultimedio

İlgili konular