2014-12-11 16 views
5

mam zamiar używać STI w Rails z następujących modeli:Określ unikalne atrybuty modeli dziecko w szynach przy użyciu STI

class Promo < ActiveRecord::Base 
end 

class Event < Promo 
end 

class Discount < Promo 
end 

Istnieją tylko kilka różnic pod względem cech między Event i Discount więc postać STI to dobra droga.

Nie jestem pewien, w jaki sposób zapewnić, że, na przykład, tylkoEvent posiada dodatkowy atrybut image_filename. Rozumiem, że będzie to w tabeli promos i że musi być NULL -able w przypadku, gdy wstawię wiersz Discount. Jak mogę się upewnić, że obiekt Discount nic nie wie o atrybucie (tj. Nie jest wymieniony w Discount.column_names i/lub nie może go ustawić) i że Event o tym wie?

+0

Myślę, że nie jest możliwe, że klasa dzieci nie wie o klasie rodzicielskiej, ale możesz napisać walidację w klasach dla dzieci – rderoldan1

+0

@ rderoldan1 Może nie rozumiem, ale nie wiem. t chce, aby klasa "Discount" wiedziała o swoim rodzeństwie ('Event')' image_filename' atrybut – kubasub

+0

tak, ale w twojej tablicy promocyjnej masz kolumnę 'image_filename', atrybut w rzeczywistości jest własnością Promo, inne rzeczy są gdzie używasz go – rderoldan1

Odpowiedz

4

Myślę, że koncepcja jest inna, natomiast klasa Promo dziedziczą ActiveRecord::Base następnie wszystkie klasy potomne dziedziczą jego atrybuty, tak, nazwy kolumn są wspólne we wszystkich STI. ale nadal można ustawić kolumny image_filename jako NULL w PB i zatwierdź go w swoich modelach, dzięki czemu będą w stanie przechowywać i aktualizować rekord z siedzibą w danym przypadku ze coś takiego:

class Promo < ActiveRecord::Base 
    #Common validations 
    validates :name, presence: true 
    validates :user, presence: true 
end 

class Event < Promo 
    #event related validations 
    validates image_filename, presence: true 
end 

class Discount < Promo 
    #discount related validations 
    validates percentage, presence: true 
end 

Oto świetny samouczek http://samurails.com/tutorial/single-table-inheritance-with-rails-4-part-1/

+1

Myślę, że typ sprawdzania poprawności, który byłby najlepszy do "wymuszenia" 'nazwa_pliku obrazu' nieużywany z' Rabatem' to 'sprawdzania poprawności: nazwa_pliku obrazu, nieobecność: prawda' – kubasub

+0

Zgadzam się z tobą, pokazałem ci tylko przykład jak implementować tego rodzaju sprawdzania poprawności – rderoldan1

1

Ustawienie STI oznacza, że ​​będziesz mieć 2 różne formularze dla każdej klasy dziecka. Oznacza to, że pola będą dostępne w formularzu odpowiednio dla Event i dla Discount, więc jeśli zapiszesz rekord Discount, drugie pole image_file będzie domyślnie miało wartość nil (jeśli nie zmieniłeś go na coś innego) .

Teraz wszystkie atrybuty klasy Promo rzeczywistości są metody, które można przesłonić, więc jeśli w Discount zrobisz:

def additional_image_filename #name of the attribute 
    nil 
end 

będzie zawsze zwraca zero w wyniku bez względu na to, co zostało zapisane tam . Przykładem w konsoli opartej na moim app, gdzie zastąpi atrybut name (nie, że muszę, po prostu pokazując):

2.1.5 :028 > Recipe.last 
    Recipe Load (0.2ms) SELECT "recipes".* FROM "recipes" ORDER BY "recipes"."id" DESC LIMIT 1 
=> #<Recipe id: 4, name: "Potatoes Au Gratin", instructions: nil, created_at: "2014-12-04 12:54:26", updated_at: "2014-12-04 12:54:26"> 
2.1.5 :029 > Recipe.last.name 
    Recipe Load (0.4ms) SELECT "recipes".* FROM "recipes" ORDER BY "recipes"."id" DESC LIMIT 1 
=> nil 

jak widać nie jest to nazwa w bazie danych i ma wartość, ale zwraca nil ponieważ został on przesłonięty.

Możesz również dodać sprawdzanie poprawności dla oddzielnych klas lub wywołań zwrotnych, które pozwolą oczyścić atrybuty, których nie potrzebujesz, tak zwane additional_image_filename, ale nie rozumiem, dlaczego tego potrzebujesz. w każdym formularzu będziesz miał osobnych kontrolerów i akcje, dlatego też będą różne permitted_params, które pozwolą Ci wybrać, które pola powinny być tylko zapisane.

W skrócie:

  1. Nie obejmują additional_image_filename w formie do Rabat
  2. Nie zawierają additional_image_filename w peritted_params w akcji kontrolera do dyskonta
  3. Ustaw wartość jako zero w db lub przesłonić metoda w klasie Discount, jak opisano powyżej.
+0

Nie jestem pewien, co masz na myśli przez dodatkową kolumnę image_filename jako 'Discount' i' Event' oba mają to samo pole w bazie danych. – kubasub

+0

przez "dodatkowy image_filename" mam na myśli ten, o którym wspominasz, że masz na wydarzenie, a nie ze względu na zniżkę, nie wiem, jak się nazywa. 'additional image_filename' jest po prostu symbolem zastępczym – rmagnum2002

+0

, a jeśli tak, to czym się dzielą? w zależności od tego, jak skonfigurujesz "allowed_params" i "pola formularzy", pole będzie dostępne tylko dla wybranej klasy. – rmagnum2002