代码之家  ›  专栏  ›  技术社区  ›  Carl Edwards monkbroc

为路由预先设置UUID以确保slug的唯一性

  •  0
  • Carl Edwards monkbroc  · 技术社区  · 6 年前

    我正在使用友好的\u id向我的模型及其相应的url添加自定义slug。目前,我有一个设置,其中 Post 属于 Board . 毫无疑问,在某些情况下,一个职位的头衔与另一个职位相同,但来自不同的董事会。我经常注意到站点(包括在内)在slug之前预先设置一组唯一的数字,以确保不存在唯一性问题:

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

    我想知道实现这一目标的最佳方法是什么?这不能仅仅通过routes文件来完成,因为仍然有可能创建两个或更多相同的post。它会是一个组合,改变我的模型,路由文件,和配置友好的宝石?

    我的最终目标是为我的帖子生成如下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 回复  |  直到 6 年前
        1
  •  2
  •   luisenrike    6 年前

    您可以在路线中执行以下操作:

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

    并添加 params[:board_real_id]

    旧的

    candidates 如果两个帖子有相同的名字,并且它们属于同一个板块,只要插入帖子的id,你就可以了,你会有类似的结果 https://example.com/boards/example-board/123456-example-post

    发件人: http://norman.github.io/friendly_id/file.Guide.html

    用于指定事件中使用的备用段塞的功能 你想用的那个已经被拿走了。例如:

    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
    
        2
  •  0
  •   Mahmoud Sayed    6 年前

    slug_candidates ,参见文档 here .

    在您的例子中,您只需要在slug的末尾/开头添加一个uuid,您可以通过使用增量uuid来实现这一点。如果您有当前slug的a记录,那么获取最大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