Предварительный UUID для маршрутизации, чтобы обеспечить уникальность слаг - PullRequest
0 голосов
/ 09 октября 2018

Я использую friendly_id для добавления пользовательских моделей в свои модели и соответствующих им URL.В настоящее время у меня есть настройки, где Post принадлежит Board.Несомненно, будут случаи, когда сообщение будет иметь заголовок, идентичный другому, но с другой доски объявлений.Часто я замечал, что сайты (включая SO) добавляли уникальный набор чисел перед слагом, чтобы убедиться, что нет никаких проблем с уникальностью:

https://stackoverflow.com/questions/123456/my-example-question

Мне было интересно, что будет лучшим подходом для достижения этой цели?Это не может быть сделано исключительно через файл маршрутов, потому что все еще существует возможность создания двух или более идентичных сообщений.Будет ли это комбинация изменения моей модели, файла маршрутов и конфигурации гемов friendly_id?

Моя конечная цель - создать URL-адрес для моих сообщений, подобный этому:

https://example.com/boards/example-board/123456/example-post

class Board < ApplicationRecord
  extend FriendlyId

  has_many :posts

  friendly_id :name, use: :slugged
end


class Post < ApplicationRecord
  extend FriendlyId

  belongs_to :board

  friendly_id :title, use: :slugged
end

resources :boards do
  scope module: :boards do
    resources :posts
  end
end

Ответы [ 2 ]

0 голосов
/ 09 октября 2018

Вам нужно использовать slug_candidates, см. Документы здесь .

В вашем случае все, что вам нужно, это добавить uuid в конец / начало слага, и выможно добиться этого с помощью инкрементного uuid.Если у вас есть запись с текущим слагом, получите максимальное значение uuid и увеличьте его на 1, сохраните!

class Post < ApplicationRecord
  extend FriendlyId

  belongs_to :board

  friendly_id :slug_candidates, use: :slugged


  def slug_url
    name
  end

  def slug_candidates
    [:slug_url, [:slug_url, :slug_uuid]]
  end

  def slug_uuid
    result = Post.select("COUNT(REGEXP_SUBSTR(name, '[0-9]+$')) AS cnt, MAX(REGEXP_SUBSTR(title, '[0-9]+$')) + 1 AS mx_uuid")
    result.cnt == 0 ? "" : result.mx_uuid + 1
  end
end

Я использую синтаксис MYSQL для сопоставления с шаблоном регулярных выражений.

0 голосов
/ 09 октября 2018

РЕДАКТИРОВАТЬ

Вы можете сделать что-то подобное в своих маршрутах:

resources :boards do
  resources :posts, path: ':board_real_id'
end

и добавить params[:board_real_id] к вашему запросу.

СТАРЫЙ

Я не думаю, что вам нужен UUID для этого (если вы не хотите).Вы можете использовать candidates, и если два сообщения имеют одинаковое имя и принадлежат к одной доске, просто введите идентификатор сообщения, и все будет в порядке, у вас будет что-то вроде https://example.com/boards/example-board/123456-example-post

От: http://norman.github.io/friendly_id/file.Guide.html

Поскольку UUID ужасны, FriendlyId предоставляет функциональность «кандидатов в слаг», позволяющую вам указать альтернативные слагы для использования в случае, если тот, который вы хотите использовать, уже занят.Например:

friendly_id :slug_candidates, use: :slugged

  # Try building a slug based on the following fields in
  # increasing order of specificity.
  def slug_candidates
    [
      :name,
      [:id, :name]
    ]
  end
...