Nie każdy lubi STI (Single Table Inheritance), nie wszędzie “opłaca” się go uzyć.
Lekiem na całe zło może nie jest, ale pragnę Państwu przedstawić :
Polymorphic model
Gem umożliwia na zdefiniowanie odmian danego modelu, można też wykonywać warunkowe walidacje, czy też warunkowe callbacki!
Weźmy taki przykład:
[code=ruby]class Gallery < ActiveRecord::Base
polymorphic_model :with_type_column => :gallery_type
define_type :main, :singleton => true, :autocreate => true
define_type :private
validates_presence_of :title
validates_presence_of :owner, :if => :private?
before_validations_on_create do |gallery|
gallery.title = “Main gallery” if gallery.main?
end
end
użycie:
zawsze zwraca obiekt:
@main_gallery = Gallery.main
dla kolekcji (nie-singletonowych typów) tworzone są named scopy
@private_galleries_owners = Gallery.private.map(&:owner)[/code]
Dodatkowo gem rozszerza rspec-rails, wystarczy dodać w swoim spec_helper.rb:
require 'spec/rails/polymorphic_model'
i już można mockować polimorficzne modele:
[code=ruby] describe Gallery do
describe “main” do
before do
@gallery = mock_polymorphic_model(Gallery, :main)
end
it "should be main gallery" do
@gallery.should be_main
@gallery.should_not be_private
@gallery.gallery_type.should == "main"
end
end
end[/code]
Próba mockowania modelu w niezdefiniowanym typie rzuca wyjątek.
W planach jest dodanie bloków do metody define_type tak, by powyzszy przykład można było zapisać tak:
[code=ruby]class Gallery < ActiveRecord::Base
polymorphic_model :with_type_column => :gallery_type
define_type :main, :singleton => true, :autocreate => true do
before_validations_on_create :set_title_for_main_gallery
end
define_type :private do
validates_presence_of :owner
end
validates_presence_of :title
private
def set_title_for_main_gallery
gallery.title = “Main gallery”
end
end[/code]
Co o tym myślicie?