Rails 5.0.1 - гем Friendly_id - включен активный модуль заботы before_create или before_save

Я создал этот модуль:

приложение/модели/проблемы/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

и я включаю его в модель, вот так:

приложение/модели/plan.rb

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

но before_create не срабатывает. Столбец slug - это столбец not_null, поэтому я получаю сообщение об ошибке базы данных.

ОШИБКА: нулевое значение в столбце "слаг" нарушает ограничение ненулевого значения

Если поставить код set_slug прямо в модель, все работает. Итак, что мне здесь не хватает в отношении проблем в Rails 5?

Интересно, связано ли это как-то с использованием FriendlyId (именно поэтому я в первую очередь добавил слаги!)


person rmcsharry    schedule 18.02.2017    source источник
comment
set_slug не должен быть методом класса. Просто напишите его как обычный метод внутри модуля suggable.   -  person Pedro Nascimento    schedule 18.02.2017
comment
Это то, что я попробовал в первую очередь. Та же проблема - я обновил вопрос, чтобы вернуть код в то состояние, в котором он был у меня сначала (т.е. не как метод класса)   -  person rmcsharry    schedule 18.02.2017
comment
Изменение на before_save работает?   -  person Pedro Nascimento    schedule 18.02.2017
comment
Также вы упоминаете, что если вы добавите set_slug в модель, она будет работать. Итак, оставить included do...end в модуле и просто скопировать set_slug работает?   -  person Pedro Nascimento    schedule 18.02.2017
comment
before_save не работает. Если я копирую хук before_create И set_slug, он работает - мне нужно скопировать оба   -  person rmcsharry    schedule 18.02.2017
comment
К вашему сведению, если я оставлю хук в модуле, включу его и добавлю в модель только метод set_slug, это сработает. Странно, да?   -  person rmcsharry    schedule 18.02.2017
comment
Не могли бы вы попробовать переместить только хук before_create и посмотреть, сработает ли он? Я думаю, что проблема с блоком included.   -  person Pedro Nascimento    schedule 18.02.2017
comment
Я тоже это пробовал. Я считаю, что проблема связана с драгоценным камнем FriendlyId. Я думаю, что set_slug может быть методом, который он также использует.   -  person rmcsharry    schedule 18.02.2017
comment
Приятно знать, что вы решили это! :)   -  person Pedro Nascimento    schedule 19.02.2017


Ответы (1)


Это помог мне решить эту проблему. Friendly_Id устанавливает слаг в обратном вызове before_validation, если он равен нулю.

Поэтому мой модуль должен «прыгать» раньше этого. Таким образом, решение по созданию модуля, не конфликтующего с Friendly_id, выглядит следующим образом.

Обратите внимание, что мне нужно изменить имя метода для моего хука (поскольку set_slug — это метод, используемый Friendly_Id), И я должен использовать prepend: true. Вместе это приводит к тому, что мой код устанавливает слаг до того, как Friendly_Id запускает свою проверку, чтобы попытаться установить его.

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
person rmcsharry    schedule 18.02.2017