Search code examples
ruby-on-railscontrollerroutessingle-table-inheritance

Rails - main class, sub class, how to get all records with subclass


In using STI, I'm trying to get all pages of a specific :type.

I have a main class in pages_controller.rb

class PagesController < ApplicationController

  def index
    @pages = Page.all
  end

end

Below that, I have another class in pages_controller.rb

class Blog < Page

    def index
        @pages = Blog.all   
    end

end

Shouldn't the Blog class get all pages with a :type of "Blog"? Instead it is getting all pages regardless of the type. I've also tried @pages = Page.where(:type => "Blog") I'm accessing the URL http://localhost:3000/blog

Here are my routes

    resources :pages do
        collection do
            get :gallery
            get :list
        end     
    end
    resources :blog, :controller => :pages

Solution

  • You need to define a class for every type in app/models directory:

    # app/models/page.rb
    class Page < ActiveRecord::Base
    end
    
    # app/models/blog.rb
    class Blog < Page
    end
    

    If you want one controller to get them both:

    if blog? # implement this method yourself
      @blogs = Blog.all
    else
      @pages = Page.all
    end
    

    So in essence, the all-method returns instances of the class you called it on.

    However: I would recommend you to use separate controller for each type. They are different resources and should be treaded as such. Use tools like InheritedResources to dry up your controllers.