0

I have created this module:

app/models/concerns/sluggable.rb

module Sluggable
  extend ActiveSupport::Concern

  included do
    before_create :set_slug
  end


  def set_slug
    if self.slug.nil?
      puts 'adding slug'
      self.slug = SecureRandom.urlsafe_base64(5)
    end
  end

end

and I include it in a model, like so:

app/models/plan.rb

class Plan < ApplicationRecord
  extend FriendlyId
  friendly_id :id, :use => :slugged
  include Sluggable
end

but the before_create does not fire. The slug column is a not_null column so I get a database error.

ERROR: null value in column "slug" violates not-null constraint

If put the set_slug code directly in the model, it works. So what am I missing here about Concerns in Rails 5?

I wonder if its something related to using FriendlyId (which is why I added slugs in the first place!)

rmcsharry
  • 5,363
  • 6
  • 65
  • 108

1 Answers1

1

This helped me solve this. Friendly_Id sets the slug in a before_validation callback if it is nil.

So my module needs to 'jump' in ahead of that. So the solution to make a module that doesn't conflict with Friendly_id is as below.

Notice I need to change the method name for my hook (as set_slug is a method used by Friendly_Id) AND I have to use prepend: true. Together this causes my code to set the slug before Friendly_Id fires its check to try and set it.

module Sluggable
  extend ActiveSupport::Concern

  included do
    before_validation :set_a_slug, prepend: true
  end


  def set_a_slug
    if self.slug.nil?
      self.slug = SecureRandom.urlsafe_base64(5)
    end
  end

end
rmcsharry
  • 5,363
  • 6
  • 65
  • 108