STI - osobna walidacja

Cześć, postanowiłem zastosować STI do utworzenia nowego typu ogłoszenia RideAd. Zastanawiam się tylko czy nie zrobić tego prościej ponieważ aby dodać nowy model RideAd będę musiał dodać drugi RegularAd aby ustawić mu inną walidację, ponieważ nie potrzebuje w nim :title i :ad_content a mają one walidację vpo.

[code=ruby]#Obecny model
class Ad < ActiveRecord::Base
validates_presence_of :name, :email, :price, :category_id

:name
:phone_number
:email
:title
:ad_content
:advertiser_id
:token
:verification_date
:level
end

Po STI

class Ad < ActiveRecord::Base
validates_presence_of :name, :email, :price, :category_id, :title, :ad_content

:name
:phone_number
:email
:advertiser_id
:token
:verification_date
:level
:type
end

class RegularAd < Ad
validates_presence_of :title, :ad_content

:title
:ad_content
end

class RideAd < Ad
validates_presence_of :from, :to

:from
:to
end[/code]

[code=“ruby”]class Ad < ActiveRecord::Base
validates_presence_of :name, :email, :price, :category_id
validates_presence_of :title, :ad_content, if: is_regular?
validates_presence_of :from, :to, unless: is_regular?

def is_regular?
self.type.nil?
end

end

class RideAd < Ad

end[/code]
A tak?

Fajny pomysł :slight_smile: dzięki

Tylko jak mi kiedyś wpadnie do głowy dodać kolejny typ ogłoszenia to będę miał dużo tych vpo :slight_smile:

@regedarek:

  1. Dziedziczenie polega głównie na specjalizacji, a nie na rozszerzaniu. Przy STI jest to szczególnie istotne, bo jeśli zestaw pól będzie uzależniony od podklasy, to nagle nie da się stosować NOT NULL i nie da się zapewnić integralności danych (przynajmniej nie bez jakichś komplikacji typu triggery). Oczywiście dodatkowe pola w klasach pochodnych bywają uzasadnione, ale jeśli są główną motywacją do dziedziczenia, to coś jest nie tak.

  2. Sugeruję użyć nowego API walidacji. Nowe API wymusza grupowanie walidacji po polach (co zresztą zawsze było dobrą praktyką): http://api.rubyonrails.org/classes/ActiveModel/Validations/ClassMethods.html#method-i-validates

@qertoip dzięki za wskazówki

  1. Masz jakąś propozycję, którą można użyć zamiast STI ?
    Planuję do tego modelu RideAd dodać inne metody niż te które będą w Ad oraz używać tych, które są już w Ad dlatego wydaje mi się to sensownym rozwiązaniem.

Może powinienem użyć delegacji??
Tyle, że jak wtedy powinna wyglądać walidacja. ?

[quote=regedarek]@qertoip dzięki za wskazówki

  1. Masz jakąś propozycję, którą można użyć zamiast STI ?
    Planuję do tego modelu RideAd dodać inne metody niż te które będą w Ad oraz używać tych, które są już w Ad dlatego wydaje mi się to sensownym rozwiązaniem.[/quote]
    Nie znam przypadków użycia Twojej aplikacji wystarczająco dobrze, żeby sugerować rozwiązanie (w zasadzie w ogóle nie znam). Np. o czym to są ogłoszenia? Jakiego rodzaju ogłoszenia przewidujesz? Jakie zachowanie jest wspólne, a jakie specyficzne dla różnych ogłoszeń?

Chodzi o wyczucie, jakie rozwiązanie jest najmniejszym złem, bo w zakresie modelowania dziedziczenia w relacyjnych bazach danych dobrych rozwiązań niestety nie ma i zawsze trzeba iść na jakiś zgniły kompromis. Np. nie dziedziczyć.

Zwykłe ogloszenia jak na tablica.pl -> ale by coś ogłosić trzeba przejść potwierdzenie emaila, weryfikacje (ogłaszać można bez logowania w systemie)

Jak narazie będą tylko zwykłe ogłoszenia i ogloszenia o przejazdach(RideAd). Nic wiecej na poczaŧek nie przewiduję.

Zachowanie wspólne to dodawanie potwierdzanie i weryfikowanie ogłoszeń. (ogłoszenia róznią się polami)
RideAd ma dwa dodatkowe pola(from i to) oraz nie używa dwóch pól z zwykłych ogłoszeń(ad_content, title)

Podejrzewam, że będę miał w RideAd jakieś dodatkowe metody.

Dzięki :slight_smile:
Staram się zawczasu przewidzieć problemy :wink: