我的normalize_friendly_id override永远不会被调用



我是friendly_id的新手,它符合我提供友好url的需要👍

我有一个Group模型(即一组用户),我在创建时为其生成唯一的code。仅供参考,这个code属性被设置为我的PostgreSQL数据库中的唯一索引。

class Group < ApplicationRecord
include FriendlyId
friendly_id :code
after_create :generate_group_code
private
def normalize_friendly_id(value)
super.upcase
end
def generate_group_code(size = 8)
allowed_chars = ("a".."z").to_a
code = (1..size).map { allowed_chars[rand(26)] }.join while Group.exists?(code: code)
update(code: code)
end
end

我认为我已经遵循了gem的指南,我只是希望生成的code在url中被大写(即/group/ABCDEFGH)。

friendly_id确实被设置为我的code属性,但它没有大写。我在normalize_friendly_id方法中放置了byebug,但它从未被触发。我错过了什么?

normalize_friendly_id仅在使用slugged模块使用slug列来存储和查找该列时调用:

friendly_id :code, use: :slugged

使用这个你可以重写normalize_friendly_id方法。

Sunny的方式可能是一般的方式,因为slugged模块需要编辑内部方法,如normalize_friendly_id

在我的例子中,我已经有一个唯一的code属性。使用slugged模块将创建一个名为slug的新属性,该属性将是,与我的code完全相同。我想避免重复。

最后,我决定避开friendly_idgem并直接覆盖我的模型中的to_param方法(受此要点的启发):

class Group < ApplicationRecord
validates :code, format: { with: /A[a-z]{8}z/ }, uniqueness: true, on: :update
after_create :generate_group_code

# Override the method to allow '/group/MYGROUPA' paths 
def to_param
code.upcase
end
# A group code is made of letters exclusively.
# Converting a String (or nil) to an integer leads to 0.
# In this case, lookup by code, otherwise, lookup by id.
# Note the 'downcase', which allows URLs to be case insensitive.
def self.find(input)
input.to_i == 0 ? find_by_code!(input.downcase) : super
end
private
def generate_group_code(size = 8)
allowed_chars = ("a".."z").to_a
code = (1..size).map { allowed_chars[rand(26)] }.join while Group.exists?(code: code)
update(code: code)
end
end

如果我遇到任何副作用,我会编辑这个答案,但现在它是有效的。

最新更新