8
votes

I've used the FriendlyId gem (version 4.0.8) with a Rails application. I've followed the tutorial on RailsCasts and based on the documentation, I have to run Model.find_each(&:save) on rails console to generate slugs for old records. However, when I do this, all of my old records still have nil for their slug attributes, so it doesn't really change the url's.

Am I doing something wrong? This only happens on production by the way. It works fine on development.

Update:

My model looks like this:

class Member < ActiveRecord::Base
  extend FriendlyId
  friendly_id :name, use: :slugged

  belongs_to :gym

  attr_accessible :category, :name, :description
  validates :category, :name, :description, :presence => true

  has_attached_file :avatar, :styles => { :medium => "300x300>", :thumb => "100x100>" }

  def self.search(search)
    if search.present?
      where("name LIKE ?", "%#{search}%")
    else
      find(:all)
    end
  end

  def should_generate_new_friendly_id?
    new_record?
  end
end
2
What does your model look like?starscream_disco_party
Updated the question with the model code, thanks.gerky
Does it work if you comment out the should_generate_new_friendly_id? block?Nils Landt
Loos at this past answer for help stackoverflow.com/questions/10957505/…Kyle C
@Kyle C It's exactly what I'm experiencing. Though I've decided to manually update the slug for old records, since they're not that many. Thanks for this!gerky

2 Answers

11
votes

should_generate_new_friendly_id? is returning false since new_record? is false, since your records already exist.

Delete the should_generate_new_friendly_id? method, or try this & re-run:

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

See also: Rails Friendly_Id on Heroku, Heroku not updating slugs

2
votes

I had this same challenge when working on a Rails 6 application.

Here's how I solved it:

By default Friendly_id gem does not generate slugs for existing records in a Rails application. So if you have existing records for a model, slugs won't be generated for them. They will only be generated for newer records.

To generate slugs for existing records, do the following. Say our model name is Blog and the column we want to use for the slug is title, we will do the following:

  • Be sure to first add a slug column to the Blog table:

    rails g migration AddSlugToBlogs slug:uniq
    
  • Next, generate the friendly configuration file and a new migration (if you've not already done it):

    rails generate friendly_id
    
  • Next, run your database migration:

    rails db:migrate
    
  • Next, edit the app/models/blog.rb file as the following:

    class Blog < ApplicationRecord
      extend FriendlyId
      friendly_id :title, use: :slugged
    end
    
  • Next, edit the app/controllers/blogs_controller.rb file and replace Blog.find by Blog.friendly.find

    class BlogController < ApplicationController
      def show
        @blog = Blog.friendly.find(params[:id])
      end
    end
    

    OR

    class BlogsController < ApplicationController
      before_action :set_blog, only: %i[ show edit update destroy ]
    
      def show
      end
    
      private
      # Use callbacks to share common setup or constraints between actions.
      def set_blog
        @blog = Blog.friendly.find(params[:id])
      end
    end
    
  • Finally, start your rails console and run the command below to generate slugs for existing records:

    rails console
    
    Blog.find_each(&:save)
    

    Note: You will have to run this command in all environments where you have existing records, say, test, staging, and production, to generate slugs for the records in those environments as well.

Now, when you create a new blog like the following with say title - My first blog, you will be able to access the blog show page using the URL http://localhost:3000/blogs/my-first-blog.

That's all.

I hope this helps