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

Undefined Method 'underscore'


I'm trying my hand at STI using Thibault's tutorial: https://samurails.com/tutorial/single-table-inheritance-with-rails-4-part-3

It's been working fine up till the dynamic paths part where I get 'undefined method `underscore' for nil:NilClass' for this snippet

def format_sti(action, type, post)
    action || post ? "#{format_action(action)}#{type.underscore}" : "#{type.underscore.pluralize}"
end

Routes:

    resources :blogs, controller: 'posts', type: 'Blog' do 
          resources :comments, except: [:index, :show]
    end
    resources :videos, controller: 'posts', type: 'Video'
    resources :posts

Post controller:

    before_action :set_post, only: [:show, :edit, :update, :destroy]
    before_action :set_type
    def index
        @posts = type_class.all
    end
    ...
    private 

    def set_type
        @type = type
    end

    def type
        Post.types.include?(params[:type]) ? params[:type] : "Post"
    end

    def type_class
        type.constantize
    end

    def set_post
        @post = type_class.find(params[:id])
    end

Posts Helper:

    def sti_post_path(type = "post", post = nil, action = nil)
        send "#{format_sti(action, type, post)}_path", post 
    end

    def format_sti(action, type, post)
        action || post ? "#{format_action(action)}#{type.underscore}" : "#{type.underscore.pluralize}"
    end

    def format_action(action)
        action ? "#{action}_" : ""
    end

Post index.html

    <% @posts.each do |p| %>

    <h2><%= p.title %></h2>
    Created at: <%= p.created_at %><BR>
    Created by: <%= p.user.name %><P>
    <%= link_to 'Details', sti_post_path(p.type, p) %><P>
    <% end %>

The error appears when I try to access index.html, and I haven't tried other links yet. I've tried removing 'underscore', then '_path' becomes an undefined method. I've also tried other suggestions such as 'gsub', but it also shows it as an undefined method, which leads me to think that it's a syntax error...

UPDATE: I had attr_accessor :type and that made 'type' nil. So I removed that and now it is working


Solution

  • In your PostsHelper.rb

    def format_sti(action, type, post)
        action || post ? "#{format_action(action)}#{type.underscore}" : "#{type.underscore.pluralize}"
    end
    

    This method's else portion has type.underscore. type may be nil here. To verify it, try this:

    def format_sti(action, type, post)
        action || post ? "#{format_action(action)}#{type.underscore}" : "#{"post".underscore.pluralize}"
    end