10

que tienen un problema con mi códigoITS y polimorfos

class Post < ActiveRecord::Base 
end 

class NewsArticle < Post 
    has_many :comments, :as => :commentable, :dependent => :destroy, :order => 'created_at' 
end 

class Comment < ActiveRecord::Base 
    belongs_to :commentable, :polymorphic => true, :counter_cache => true 
end 

Y el intento de ir a buscar los comentarios de algunos NewsArticle que veo en los registros de algo así como

Comment Load (0.9ms) SELECT "comments".* FROM "comments" WHERE ("comments"."commentable_id" = 1 and "comments"."commentable_type" = 'Post') ORDER BY created_at 

extraño que "commentable_type" = 'Post '. ¿Qué pasa?

PS: Carriles 2.3.5 & & rubí 1.8.7 (2010-01-10 Patchlevel 249) [i686-darwin10]

Respuesta

5

El campo commentable_type necesita almacenar el nombre de la tabla que contiene el datos, una vez que esa fila se carga desde la tabla correcta, el tipo heredado se cargará desde la columna tipo en la tabla Publicaciones.

Así:

Aquí los puntos de comentario a la mesa que se comenta. La tabla de mensajes, ID 1

>> Comment.first 
=> #<Comment id: 1, commentable_id: 1, commentable_type: "Post", body: "test", created_at: "2010-04-09 00:56:36", updated_at: "2010-04-09 00:56:36"> 

continuación para cargar el NewsArticle, ID 1 se carga desde los puestos, y el tipo no indica un NewsArticle.

>> Comment.first.commentable 
=> #<NewsArticle id: 1, type: "NewsArticle", name: "one", body: "body", created_at: "2010-04-09 00:55:35", updated_at: "2010-04-09 00:55:35"> 
>> Comment.first.commentable.class.table_name 
=> "posts" 

Si commentable_type celebrada "NewsArticle" tendría que mirar a la clase para determinar la tabla. De esta manera, puede simplemente mirar a la mesa y preocuparse por el tipo una vez que llega allí.

+0

eh ... el nombre de la tabla es correcto, pero el nombre del modelo STI es incorrecto –

+0

Para la relación polimórfica, solo importa la tabla, una vez que se carga esa tabla, se puede determinar el tipo de herencia. – danivovich

1

Eche un vistazo a la sección Asociaciones polimórficas de ActiveRecord::Associations API. Hay un poco sobre el uso de asociaciones polimórficas en combinación con la herencia de tablas únicas. Tras el segundo ejemplo de código en esa sección Creo que esto podría estar cerca de lo que quiere

class Comment < ActiveRecord::Base 
    belongs_to :commentable, :polymorphic => true, :counter_cache => true 

    def commentable_type=(sType) 
    super(sType.to_s.classify.constantize.base_class.to_s) 
    end 
end 

class Post < ActiveRecord::Base 
    has_many :comments, :as => :commentable, :dependent => :destroy, :order => 'created_at' 
end 

class NewsArticle < Post 
end 
0

Técnicamente, no hay realmente nada de malo en esto. Cuando Rails está tratando con una asociación polimórfica, y el objeto asociado está usando STI, simplemente usa la clase base como el tipo (en su caso "commentable_type").

Si publica Post y NewsArticle en tablas separadas, obviamente el tipo commentable_type se mostrará como Post y NewsArticle respectivamente.

+0

¿Cómo puede recuperar los comentarios de NewsArticle si esto es correcto? Tengo un problema similar en el que mi consulta no devuelve nada porque está buscando el tipo de clase base. – sweetroll

1

def commentable_type = (sType) super (sType.to_s.classify.constantize.base_class.to_s) final

Este método está volviendo clase como Post, qué hacer si se desea almacenar la clase heredada Publicar como commentable_type?

1

Buena pregunta. Tenía exactamente el mismo problema con Rails 3.1. Parece que el problema no está resuelto todavía. Aparentemente, usar asociaciones polimórficas en combinación con herencia de tabla única (ITS) en Rails es un poco complicado.

La documentación actual de Rails para Rails 3.2 da este consejo para combinar polymorphic associations and STI:

Uso de asociaciones polimórficas en combinación con una sola mesa herencia (STI) es un poco difícil. Para que las asociaciones a funcionen como se esperaba, asegúrese de guardar el modelo base para los modelos STI en la columna de tipo de la asociación polimórfica.

En su caso, el modelo base sería "Publicar", es decir, "commentable_type" debería ser "Publicar" para todos los comentarios.

Cuestiones relacionadas