ruby-on-railsrubyrubygemsfriendly-id

Rails Undefined method `friendly_id' using friendly_id gem


I've looked at similar posts on SO and YouTube videos, but can't seem to figure out why I'm getting this error for a blog site:

undefined method `friendly_id' for BlogPost:Class

Ideally, my URL should be: www.mysite.com/blog-title-here

blog_post.rb model

class BlogPost < ApplicationRecord
  # This ensures a blog title and message are present in the form
  has_rich_text :content
  validates :title, presence: true
  validates :content, presence: true
  attribute :published_at, :datetime

  extend friendly_id :title, use: :slugged

  def next
    BlogPost.where('id > ?', id).first
  end

  def prev
    BlogPost.where('id < ?', id).last
  end

  def should_generate_new_friendly_id?
    title_changed? || slug.blank?
  end
end

blog_post_controller.rb

class BlogPostsController < ApplicationController
  before_action :authenticate_user!, except: [:index, :show]
  before_action :set_blog_post, only: [:show, :edit, :update, :destroy]

  def index
    @blog_posts = BlogPost.all
    @blog_posts = BlogPost.order(created_at: :desc)
  end

  def show
    @next_blog_post = @blog_post.next
    @prev_blog_post = @blog_post.prev
  end

  def new
    @blog_post = BlogPost.new
  end

  def create
    @blog_post = BlogPost.new(blog_post_params)
    if @blog_post.save
      # Redirect to the show page for the newly created blog post
      redirect_to @blog_post
    else
      # Else, render the new template again
      render :new, status: :unprocessable_entity
    end
  end

  def edit
  end

  def update
    if @blog_post.update(blog_post_params)
      redirect_to @blog_post
    else
      render :edit, status: :unprocessable_entity
    end
  end

  def destroy
    @blog_post.destroy
    redirect_to root_path
  end

  private

  def blog_post_params
    params.require(:blog_post).permit(:title, :content, :published_at)
  end

  def set_blog_post
    @blog_post = BlogPost.friendly.find(params[:id])
  rescue ActiveRecord::RecordNotFound
    redirect_to root_path
  end

  def authenticate_user!
    redirect_to new_user_session_path, alert: 'Please sign in to continue.' unless user_signed_in?
  end
end

This is a section of my schema file:


  create_table "blog_posts", force: :cascade do |t|
    t.string "title"
    t.datetime "created_at", null: false
    t.datetime "updated_at", null: false
    t.datetime "published_at"
    t.string "slug"
    t.index ["slug"], name: "index_blog_posts_on_slug"
  end

  create_table "friendly_id_slugs", force: :cascade do |t|
    t.string "slug", null: false
    t.integer "sluggable_id", null: false
    t.string "sluggable_type", limit: 50
    t.string "scope"
    t.datetime "created_at"
    t.index ["slug", "sluggable_type", "scope"], name: "index_friendly_id_slugs_on_slug_and_sluggable_type_and_scope", unique: true
    t.index ["slug", "sluggable_type"], name: "index_friendly_id_slugs_on_slug_and_sluggable_type"
    t.index ["sluggable_type", "sluggable_id"], name: "index_friendly_id_slugs_on_sluggable_type_and_sluggable_id"
  end

I'm not sure if I'm getting this error because I don't use 'name' as per the schema, but rather 'title' for BlogPost title.

I have restarted the server. Done rails db:migrate. Tried to update the schema but this did not work.


Solution

  • Documentation says you should use friendly_id in model like this:

    class User < ApplicationRecord
      extend FriendlyId
      friendly_id :attribute_name, use: :slugged
    end