Rails gem friendly_id: как получить предварительный просмотр слага в реальном времени до того, как его объект будет создан

Используя гем Rails «friendly_id», можно ли получить «живой предварительный просмотр» создаваемого слага? До того, как объект будет сохранен, то есть (и будет возвращен при наборе текста с помощью запроса ajax)?

Если да, то как?


person TomDogg    schedule 09.12.2013    source источник
comment
Комитет должен спросить, читали ли вы исходный код, смотрели ли автоматические тесты, отлаживали ли вы .save() вызов и т. д.   -  person Phlip    schedule 10.12.2013
comment
Осведомленность обвиняемого может быть не настолько обширной, как того требует присяжные, но он заявляет: невиновен.   -  person TomDogg    schedule 10.12.2013


Ответы (2)


Автор FriendyId здесь.

Для этого FriendlyId внутренне использует приватный set_slug. Этот метод вызывается через обратный вызов before_validation. Если по какой-то причине вы не хотите вызывать valid?, вы можете вызвать метод set_slug через send или определить в своей модели метод, который его вызывает:

instance = ModelClass.new
instance.send(:set_slug)

# or
class ModelClass < ActiveRecord::Base
  friendly_id :name, use: :slugged

  def generate_slug_preview
    set_slug
  end
end 

Однако обратите внимание, что обход или игнорирование проверок часто является плохой идеей. Например, если ваша модель включала проверку поля name, а затем вы использовали это поле в качестве основы для слага, то вы предварительно просматриваете слаг, который никогда не будет создан.

person Norman Clarke    schedule 10.12.2013
comment
Автор FriendyId дружелюбен! :) - person TomDogg; 10.12.2013

По https://github.com/norman/friendly_id/blob/master/test/slugged_test.rb ...

  m1 = model_class.new :name => "a b c d"
  m1.valid?
  assert_equal "a-b-c-d", m1.slug

Похоже, это просто .slug. В других тестах вам не нужен create — подойдет new. Итак, ваша стратегия:

  • добавить обработчик onchange в текстовое поле
  • каждый раз, когда пользователь изменяет его, используйте Ajax для отправки текущего значения на сервер
  • new экземпляр вашей модели с именем или любым другим значением, установленным для значения, отправленного Ajax
  • вызовите slug и отправьте результат обратно на веб-страницу
  • отображать его на веб-странице

Все это стандартные вещи Ajax, не имеющие ничего общего с friendly_id. Но все это заставляет меня задаться вопросом, позволит ли friendly_id отредактировать краткую информацию, поскольку вы показываете слаг пользователю, как это делают высококлассные блоги.

И вы, вероятно, должны сначала позвонить valid?.

person Phlip    schedule 09.12.2013
comment
Спасибо - к сожалению, вызов чего-то вроде Article.new(title: "A new article").slug возвращает ноль... - person TomDogg; 10.12.2013
comment
Ваше решение правильное (оно вернуло ноль, потому что моя модель прошла проверку, которая не удалась, потому что я передал ей только одно значение для атрибута, необходимого для создания слага). Итак, мне придется сделать все проверки условными, то есть validates :name, unless: :on_the_fly, а затем добавить к модели attr_accessor :on_the_fly и суммировать для нее значение true каждый раз, когда пользователь ajax-отправляет свое значение для проверки. (С другой стороны, это не кажется безопасным, поскольку позволяет любому обойти проверку.) - person TomDogg; 10.12.2013
comment
Tx, но это решение отстой. Валидации Rails отстой, потому что валидации относятся к форме, а не к модели. (Например, разные пользователи, видя разные формы, могут проходить разные проверки.) Значит, friendly_id не должен требовать .valid? call to pass просто для создания пули. - person Phlip; 10.12.2013
comment
Вызов Article.new(title: "A new article").slug возвращает nil, потому что вы не вызывали valid?, поэтому слаг так и не был сгенерирован. Валидации на самом деле важны для генерации слагов, потому что во многих случаях входные данные для метода слагов поступают из поля с валидациями, поэтому они абсолютно должны быть частью процесса валидации. Вы можете обойти это, как я описал в своем ответе здесь, в случае, если вы создаете слаг из ввода, который не имеет связанных с ним проверок. - person Norman Clarke; 10.12.2013
comment
Точка. Я должен был более тщательно отделить, почему валидации Rails отстой, от того, почему они нужны friendly_id. - person Phlip; 10.12.2013