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!)
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