我的 normalize_friendly_id 覆盖从未被调用
My normalize_friendly_id override is never called
我是 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
,但它从未被触发。我错过了什么?
只有在使用slugged
模块时才调用normalize_friendly_id
,使用slug
列来存储,通过该列查找:
friendly_id :code, use: :slugged
然后您可以使用它覆盖 normalize_friendly_id
方法。
可能是一般的方法,因为需要 slugged
模块来编辑内部方法,例如 normalize_friendly_id
.
在我的例子中,我已经有一个唯一的 code
属性。使用 slugged
模块将创建一个名为 slug
的新属性,它与我的 code
完全 相同。我想避免这种重复。
最后,我决定避开friendly_id
gem,直接重写我模型的to_param
方法(启发by this gist):
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
如果我遇到任何副作用,我会编辑这个答案,但现在它有效。
我是 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
,但它从未被触发。我错过了什么?
只有在使用slugged
模块时才调用normalize_friendly_id
,使用slug
列来存储,通过该列查找:
friendly_id :code, use: :slugged
然后您可以使用它覆盖 normalize_friendly_id
方法。
slugged
模块来编辑内部方法,例如 normalize_friendly_id
.
在我的例子中,我已经有一个唯一的 code
属性。使用 slugged
模块将创建一个名为 slug
的新属性,它与我的 code
完全 相同。我想避免这种重复。
最后,我决定避开friendly_id
gem,直接重写我模型的to_param
方法(启发by this gist):
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
如果我遇到任何副作用,我会编辑这个答案,但现在它有效。