ORYON100
ORYON100

Reputation: 103

friendly_id slugs keep returning nil causing ActiveRecord error

i am just introduced categories to my blog and i already had friendly working on posts. so i decided to integrate it onto categories aswell. the problem is i keep getting the error Couldn't find Category with 'id'=test-2 and also ActiveRecord::RecordNotFound in CategoriesController#show Please understand that i have tried implementing the many solutions i found here but i just couldn't get it to work

class CategoriesController < ApplicationController

  before_action :find_category, only: [:show, :update, :edit, :destroy]

   def index
    @categories = Category.all
   end

  def new 
    @category = Category.new
  end

  def create
    @category = Category.new(category_params)
    if @category.save
      flash[:success] = "Category created"
      redirect_to categories_path

    else
      render 'new'
    end
  end

  def edit

  end

  def update
    if @category.update(category_params)
      flash[:success]="name was successfully updated"
      redirect_to category_path(@category)
    else
      render 'edit'
    end
  end

  def show

  end

  private
  def category_params
    params.require(:category).permit(:name)
  end

  def find_category
    @category = Category.friendly.find(params[:id])
  end

end

now the weird pard is when i get into the rails console and try updating the slugs, it shows them as below:

Category.find_each(&:save)
  Category Load (0.3ms)  SELECT  "categories".* FROM "categories"  ORDER BY "categories"."id" ASC LIMIT 1000
   (0.1ms)  begin transaction
  Category Exists (0.1ms)  SELECT  1 AS one FROM "categories" WHERE ("categories"."id" != 1) AND "categories"."slug" = ? LIMIT 1  [["slug", "sports"]]

Above we can see it says slug, sports.. which is great but when i do a find... the slug appears to be nil as below:

2.3.0 :058 > c = Category.find(1)
  Category Load (0.8ms)  SELECT  "categories".* FROM "categories" WHERE "categories"."id" = ? LIMIT 1  [["id", 1]]
 => #<Category id: 1, name: "sports", created_at: "2016-07-28 15:12:13", updated_at: "2016-07-28 15:12:13", slug: nil> 

and i also tried to confirm this by trying to find the actual slug:

2.3.0 :051 > Category.find(1).slug
  Category Load (0.2ms)  SELECT  "categories".* FROM "categories" WHERE "categories"."id" = ? LIMIT 1  [["id", 1]]
 => nil 

slug seems to be nil.

and finally, just in case it is relevant... this is my show.html.erb

<h1 align="center"><%= "Category: " + @category.name %></h1>
<div align = "center">
  <% if user_signed_in? %>
     <div id="admin_links">
       <%= link_to "Edit", edit_category_path(@category) %>
       <%= link_to "Delete", category_path(@category), method: :delete, data: {confirm: "Are you sure you want to delete?"} %>
     </div>
   <% end %>

   <%= link_to "Edit Category name", edit_category_path(@category) %>

</div>

here is the category.rb

class Category < ActiveRecord::Base
  extend FriendlyId
  friendly_id :name, use: :slugged
  has_many :category_posts
  has_many :posts, through: :category_posts


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

When i do Category.first(5) in console, this is the result

Category Load (0.3ms)  SELECT  "categories".* FROM "categories"  ORDER BY "categories"."id" ASC LIMIT 5
 => [#<Category id: 1, name: "sports", created_at: "2016-07-28 15:12:13", updated_at: "2016-07-28 15:12:13", slug: nil>,
    #<Category id: 2, name: "Nerd", created_at: "2016-07-28 17:33:35", updated_at: "2016-07-28 17:33:35", slug: nil>,
    #<Category id: 3, name: "testing", created_at: "2016-07-28 17:38:22", updated_at: "2016-07-28 17:39:23", slug: nil>,
    #<Category id: 4, name: "test 2", created_at: "2016-07-28 19:10:18", updated_at: "2016-07-28 19:10:18", slug: nil>,
    #<Category id: 5, name: "books", created_at: "2016-07-28 19:29:18", updated_at: "2016-07-28 19:29:18", slug: nil>

Upvotes: 2

Views: 1078

Answers (2)

Ryan Bigg
Ryan Bigg

Reputation: 107728

In your Category model you have attr_accessor :slug, which will override the setter method that is being used for the field in the database. This means that the slug field will not be saved.

Remove attr_accessor :slug from your model + recreate the instances again to regenerate the slugs.

Upvotes: 3

Nic Nilov
Nic Nilov

Reputation: 5156

When using friendly_id you need to replace your finders with its method. Instead of

@category = Category.find(params[:id])

use

@category = Category.friendly.find(params[:id])

Regarding the slugs not being filled out, make sure that in your Category model you have something like this:

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

    # ...
end

Upvotes: 2

Related Questions