10

I'm using friendly_id 5.0.0.rc1, and also active_admin.

It would appear everything is working perfectly as expected, except for the fact that updating a record's slug attribute/column in active_admin does not do anything (it keeps it the same)

I find the same behavior just using console:

p = Post.first
p.slug
#=> 'test'
p.slug = 'another-test'
p.save
#=> true
p.slug
#=> 'test

My config:

FriendlyId.defaults do |config|
  config.use :reserved

  config.reserved_words = %w(admin new edit index session users register)

  config.use :finders

  config.use :slugged

  config.slug_column = 'slug'

  config.sequence_separator = '-'

  config.use Module.new {
    def should_generate_new_friendly_id?
      slug.blank? || slug_changed?
    end
  }
end

My model:

class Post < ActiveRecord::Base

  default_scope { order('created_at DESC') }

  validates :title, presence: true
  validates :body,  presence: true
  validates :views, presence: true, numericality: { only_integer: true }

  extend FriendlyId
  friendly_id :title, use: [:slugged, :history]

end

my controller:

class PostsController < ApplicationController

  def index
    @posts = Post.all.page(params[:page]).per(10)
  end

  def show
    @post = Post.find_by_slug!(params[:id])

    if request.path != post_path(@post)
      redirect_to @post, :status => :moved_permanently and return
    else
      @post.increment :views if @post
    end

  end

end

Thanks!

Tallboy
  • 12,847
  • 13
  • 82
  • 173
  • Maybe I'm thinking the wrong way, but your configuration states that it should generate a new slug when the slug column changed. So if you manually alter the value of the slug column and you save the record I'd assume that the generation process gets triggered which results in the old slug since the title didn't change!? – Vapire Sep 28 '13 at 22:54
  • 1
    To answer your question : it does not trigger. And by default, they explain the opposite. So you need to have your def should_generate_new_friendly_id? in every models. – Ben Nov 10 '14 at 18:00

3 Answers3

25

Usually when using friendly id, you never update the slug manually. Instead:

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

And then every time you change the title, it will automatically update the slug.

AJcodez
  • 31,780
  • 20
  • 84
  • 118
  • 1
    The config.use Module.new{ } part located in the config file (which obviously would prevent you from repeating the should_generate_new_friendly_id method in every model) is simply ignored. Very misleading as it is well explained at the end of the default config file – Ben Nov 10 '14 at 17:55
  • Something I don't get right here... What's up to date now then ? I'd like to know. It is still explained like this in their default config file – Ben Nov 10 '14 at 18:27
  • @Ben man if you don't like the answer, edit it. That's all i meant. I don't use FriendlyId or Rails anymore. – AJcodez Nov 10 '14 at 20:04
  • my bad; what i meant was misleading is friendly_id, not your answer. As they do explain it this way too. What would you recommend to use ? – Ben Nov 10 '14 at 20:08
  • @Ben ah got you. Um usually only a few models need a friendly_id, so you should specify each time in the model (usually different fields comprise the slug). – AJcodez Nov 10 '14 at 20:25
3

more exactly, you should use self.title_changed?

def should_generate_new_friendly_id?
  slug.blank? || self.title_changed?
end
ndnenkov
  • 35,425
  • 9
  • 72
  • 104
Tan Nguyen
  • 3,281
  • 1
  • 18
  • 18
0

Incase anyone else lands here and just need to change a slug:

p = Post.first
p.slug
#=> 'test'
tmp_title = p.title
p.title = 'another-test'
p.slug = nil
p.save
#=> true
p.title = tmp_title
p.slug
#=> 'another-test'
user1881102
  • 166
  • 2
  • 4