Вот решение, которое не использует наследование одной таблицы для публикаций. Это означает, что вместо одной таблицы публикаций есть таблицы статей, книг и глав. Вот команды, которые нужно запустить для создания приложения:
$ rails myproject
$ cd myproject
$ script/generate model book name:string
$ script/generate model chapter name:string
$ script/generate model article name:string
$ script/generate model citation publication_type:string publication_id:integer reference_type:string reference_id:integer
Создать этот файл в lib/acts_as_publication.rb
:
module ActsAsPublication
def self.included(base)
base.extend(ClassMethods)
end
module ClassMethods
def acts_as_publication
has_many :citations, :as => :publication
has_many :references, :as => :reference, :class_name => "Citation"
end
end
end
Создать этот файл в config/initializers/acts_as_publication.rb
:
ActiveRecord::Base.send(:include, ActsAsPublication)
Затем назовите это в каждой модели, Статье, Книге и Главе следующим образом:
class Article < ActiveRecord::Base
acts_as_publication
end
Затем добавьте эти отношения в app/models/citation.rb
:
class Citation < ActiveRecord::Base
belongs_to :publication, :polymorphic => true
belongs_to :reference, :polymorphic => true
end
Теперь мы можем создать БД и попробовать ее из консоли:
$ rake db:migrate
$ script/console
Loading development environment (Rails 2.2.2)
>> a = Article.create!(:name => "a")
=> #<Article id: 1, ...>
>> b = Article.create!(:name => "b")
=> #<Article id: 2, ...>
>> Citation.create!(:publication => a, :reference => b)
=> #<Citation id: 1, publication_type: "Article", publication_id: 1, reference_type: "Article", reference_id: 2, created_at: "2009-02-15 13:14:27", updated_at: "2009-02-15 13:14:27">
>> a.citations
=> [#<Citation id: 1, ...>]
>> a.references
=> []
>> b.citations
=> []
>> b.references
=> [#<Citation id: 1, ...>]
>> Book.create!(:name => "foo")
=> #<Book id: 1, name: "foo", created_at: "2009-02-15 13:18:23", updated_at: "2009-02-15 13:18:23">
>> a.citations.create(:reference => Book.first)
=> #<Citation id: 2, publication_type: "Article", publication_id: 1, reference_type: "Book", reference_id: 1, created_at: "2009-02-15 13:18:52", updated_at: "2009-02-15 13:18:52">
>> Book.first.references
=> [#<Citation id: 2, ...>]
>> a.citations
=> [#<Citation id: 1, publication_type: "Article", publication_id: 1, reference_type: "Article", reference_id: 2, created_at: "2009-02-15 13:14:27", updated_at: "2009-02-15 13:14:27">, #<Citation id: 2, publication_type: "Article", publication_id: 1, reference_type: "Book", reference_id: 1, created_at: "2009-02-15 13:18:52", updated_at: "2009-02-15 13:18:52">]