rails query left includes generate association active sql ruby-on-rails activerecord

sql - query - Relaciones de registro activas difíciles-poliforma bidireccional autorreferencial



rails generate model (3)

¿Cómo modelarías las referencias y citas de publicaciones (artículos, libros, capítulos, etc.)?

Una publicación puede ser un artículo, un libro o un capítulo y tiene muchas referencias a otras publicaciones y otras publicaciones hacen referencia a ella (llame a estas citas)

Necesito poder enumerar las relaciones entre las publicaciones: las referencias en una publicación y las citas de otras publicaciones a esta publicación

Mi comprensión inicial es que esta sería una relación polimórfica para manejar los diferentes tipos de publicaciones y que requeriría una unión bidireccional.

Mi puñalada

Publication belongs_to :writing, :polymorphic =>true has_and_belongs_to_many :references :class_name => "Publication" :join_table => ''reference_citation'' :foreign_key => ''reference_id'' :foreign_key => ''citation_id'' Book, Chapter, Article all have: has_many :publications :as =>writing

Encuentro esto un poco confuso por lo que cualquier sugerencia que pueda ayudar a aclararlo sería genial. Incluso sugerencias de nombres de objetos y campos.

[Solicité una versión menos clara de esta pregunta aquí .]

También es probable que necesite utilizar tiene muchos porque voy a necesitar la capacidad de destruir la relación



Aquí hay una solución que no usa la herencia de tabla única para las publicaciones. Eso significa que hay artículos, libros y tablas de capítulos, en lugar de una tabla de publicaciones. Aquí están los comandos para ejecutar para crear la aplicación:

$ 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

Cree este archivo en 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

Cree este archivo en config/initializers/acts_as_publication.rb :

ActiveRecord::Base.send(:include, ActsAsPublication)

Luego llame a eso en cada modelo, artículo, libro y capítulo, así:

class Article < ActiveRecord::Base acts_as_publication end

A continuación, agregue estas relaciones en la app/models/citation.rb :

class Citation < ActiveRecord::Base belongs_to :publication, :polymorphic => true belongs_to :reference, :polymorphic => true end

Ahora podemos crear el DB y probarlo desde la consola:

$ 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">]


Aquí hay una solución que usa una relación autorreferencial usando herencia de tabla única. Use estos comandos para crear la aplicación:

$ rails myproject $ cd myproject $ script/generate model publication type:string name:string $ script/generate model citation publication_id:integer reference_id:integer

La configuración de las relaciones de esta manera:

class Publication < ActiveRecord::Base has_many :citations has_many :cited_publications, :through => :citations, :source => :reference has_many :references, :foreign_key => "reference_id", :class_name => "Citation" has_many :refered_publications, :through => :references, :source => :publication end class Citation < ActiveRecord::Base belongs_to :publication belongs_to :reference, :class_name => "Publication" end class Article < Publication end class Book < Publication end class Chapter < Publication end

Ahora podemos crear el DB y probarlo desde la consola:

$ rake db:migrate $ script/console Loading development environment (Rails 2.2.2) >> a = Article.create!(:name => "Article") => #<Article id: 1, ...> >> b = Book.create!(:name => "Book") => #<Book id: 2, ...> >> a.citations.create(:reference => b) => #<Citation id: 1, publication_id: 1, reference_id: 2, created_at: "2009-02-15 14:13:15", updated_at: "2009-02-15 14:13:15"> >> a.citations => [#<Citation id: 1, ...>] >> a.references => [] >> b.citations => [] >> b.references => [#<Citation id: 1, publication_id: 1, reference_id: 2, created_at: "2009-02-15 14:13:15", updated_at: "2009-02-15 14:13:15">] >> a.cited_publications => [#<Book id: 2, type: "Book", name: "Book", created_at: "2009-02-15 14:11:00", updated_at: "2009-02-15 14:11:00">] >> a.refered_publications => [] >> b.cited_publications => [] >> b.refered_publications => [#<Article id: 1, type: "Article", name: "Article", created_at: "2009-02-15 14:10:51", updated_at: "2009-02-15 14:10:51">]