Single Table Inheritance


#1

Muy buenas,

Tengo un pequeño problema con la herencia en Rails.

Tengo gran cantidad de “Categorías”: categorías de posts, categorías
de expedientes, categorías de personas…
Resulta que estas categorías siempre tienen los mismos datos:

t.string :codigo, :size => 3, :null => false
t.string :title, :size => 80, :null => false
t.text :description

Por lo que he visto, una buena solución sería utilizar STI

class Category < AR

end

class Category::PostCategory < Category

end

…etc

Esto lo tengo claro, simplemente metiendo el t.string :type en la
migración de categoría ya conseguiría esto.

Pero no termina de convencerme STI, por el tema de los controladores y
las vistas.

  • Tengo que tener tantos controladores como modelos??? Hacen lo mismo.
  • Si las vistas son iguales (excepto en el título), he de repetirlas??
    Esto lo podría solucionar con partials.

Mi idea sería organizarlo
así:
app
models
category.rb

category
post_category.rb
expediente_category.rb

controllers
categories_controller.rb

views
categories
show.html.erb

post_categories
expedientes_categories\

Sabéis de algún howto, post o libro dónde quede bien explicado STI,
con algún ejemplo que no sea el típico del Manager < Employee <
Person???

Sé que quizá la pregunta no esté hecha del todo bien, pero lo que
quiero a fin de cuentas es poder organizar las diferentes “Categorías”
mejor de lo que lo hago.

Gracias por adelantado!

Un saludo!


#2

Te puedo decir que yo estoy usando algo así con muy buen resultado. Para
los controladores, me limito a hacer un controlador maestro que hace
casi todo, y luego uno por cada tipo que heredan del maestro y hacen las
cosas específicas de cada uno:

class AccionesController < MasterProdController
def new
@producto = Accion.new
nuevo_producto_opinion
render :template => “productos/new”
end

Crea un nuevo producto

def create
# guardo el producto
@producto = Accion.new(params[:producto])
@producto.subtipo_id = Subtipo::ACCIONES
guarda_producto_opinion
end

end

Donde nuevo_producto_opinion y guarda_producto_opinion son funciones del
MasterProdController. Esto y poco más es el código que hay en cada
controlador…

Respecto a las vistas, si se parecen lo suficiente, es más fácil aún:
las metes en la clase genérica, y haces el render especificando el
destino (te lo he puesto en el new); en tu caso, bastaría con tener las
vistas en views/categories, no necesitas las carpetas específicas de
cada clase hija.

s2


#3

Hola de nuevo,

Me falla al intentar hacer un render “categories/new”:

class Category::ArticleCategoriesController < ApplicationController

def new
@category = Category::ArticleCategory.new
render :template => “categories/new”
end

[…]

end

undefined method `category_article_categories_path’ for
#ActionView::Base:0x3874a94

<% form_for(@category) do |f| %> <------------ FALLO!!
<%= f.error_messages %>

<%= f.label :code %>
<%= f.text_field :code %>

[…]

<%= f.submit "Create" %>

<% end %>

Un saludo!

El 17/11/2008, a las 18:35, Fernando C.
escribió:

guardo el producto


#4

Juan José Vidal Agustín wrote:

Hola de nuevo,

Me falla al intentar hacer un render “categories/new”:

class Category::ArticleCategoriesController < ApplicationController

def new
@category = Category::ArticleCategory.new
render :template => “categories/new”
end

[…]

end

undefined method `category_article_categories_path’ for
#ActionView::Base:0x3874a94

<% form_for(@category) do |f| %> <------------ FALLO!!

Estamos pensando en algo diferente… lo que yo te proponía no era lo
que haces
class Category::ArticleCategoriesController < ApplicationController
@category = Category::ArticleCategory.new

sino esto:
class ArticleCategoriesController < CategoryController

def new
@category = ArticleCategory.new
render :template => “categories/new”
end

[…]

end

Eso es lo que yo tengo, y funciona sin problemas…

s2