2010-05-20 6 views
5

Bu, doğrudan bir yanıt vermesi gerektiği gibi görünüyor, ancak Google ve SO'da çok fazla zaman geçtikten sonra bunu bulamıyorum. Doğru anahtar kelimeleri kaçırmak olabilir.Raylar: benzer karmaşık özellikleri paylaşan ActiveRecord modelleriyle DRY'yi koruma

RoR uygulamasında, özel doğrulama ve diğer işlevlere sahip belirli bir dize özniteliğini paylaşan birkaç modelim var. Düşündüğüm en yakın örnek, bir URL'yi temsil eden bir dizedir.

Bu, modellerde çok fazla çoğaltma yapılmasına (ve birim testlerinde daha fazla çoğaltma) neden olur, ancak daha fazla DRY'yi nasıl yapacağınızdan emin değilim.

Ben birkaç olası yönlere düşünebilirsiniz

...

  1. "validates_url_format_of" eklentisi, çizgisinde bir eklenti oluşturmak ama bu sadece
  2. bu özel vermek
  3. KURU doğrulamaları yapacak dize kendi modeli, ancak bu
  4. bu özel dize için bir yakut sınıf oluşturmak çok ağır bir çözüm gibi görünüyor, ama nasıl ActiveRecord bu sınıfı ilişkilendirmek olsundb

Numara 3'te bir dizedir en makul görünüyor, ama temel veri türleri dışında başka bir şey işlemek için ActiveRecord uzatmak için anlamaya olamaz modeli özniteliği ile. Herhangi bir işaretçi?

Son olarak, bunu yapmanın bir yolu varsa, klasör hiyerarşisinde, model olmayan yeni sınıfı nereye koyarsınız?

Çok teşekkürler.

GÜNCELLEME:

potansiyel bir çözüm aşağıda Matt'in mixin öneri kullanarak (ve URL örneğini kullanarak). Not, bu psuedocode'a gerçek yakuttan daha yakındır ve mükemmel sözdiziminden ziyade prensibi taşıması amaçlanmıştır.

İlk olarak bir url mixin oluşturun:

module Url 
    def url_well_formed? 
    [...] 
    end 

    def url_live? 
    [...] 
    end 
end 

Ve Site modelinde, bu modül şunlardır:

Class Site < ActiveRecord:Base 
    include Url 

    validate :url_well_formed? 
end 

Ve URL adresindeki sitesi yayında olduğunu kontrol etmek gerektiğinde, yapın ...

if site.url_live? 
    [...] 
end 

Çözmediği şey t nasıl yapılır? o birim DRY test eder. Başka bir modelim varsa, Url karışımını da kullanan Page, yine de URL için yinelenen birim testleri kümesine gerek duyar. Elbette, bunları bir yardımcıya koyabilirdim, ama bu dağınık görünüyor.

Daha temel bir çözüm var mı, yoksa aldığı kadar mı?

cevap

2

Tüm yaygın yöntemlere sahip bir modül oluşturabilir ve modülü içe aktarabilirsiniz? mixins için Google.

class CommonBase < ActiveRecord::Base 
    self.abstract_class = true # makes the model abstract 
    validate_format_of :url_field, :with => /.../ 
end 

soyut modelden Modelleri Devralma::

class User < CommonBase 
end 

class Post < CommonBase 
end 
+0

Teşekkür Matt – Greg

6

soyut bir modeli oluşturun. Karışımların beni nasıl bir yoldan çıkaracağını görebiliyorum (modellerin kendilerini güzel bir şekilde canlandırıyorlar). Şimdi ünite testlerini nasıl yapabildiğimi merak ediyorum, ama bu muhtemelen ünite testlerini modüllere eşleme konusunda daha genel bir soru.
+0

Teşekkürler KandadaBoggu. Bir soyut modele eşlenen bir birim testi oluşturabilir mi? Ve örgütsel bir soru: Bunu nereye koyardınız? – Greg

+1

Yukarıdaki özet çağrı şu şekilde olmalıdır: 'self.abstract_class = true' – tjmcewan