Rails gem“friendly_id”:如何在创建对象之前获得 slug 的实时预览
Posted
技术标签:
【中文标题】Rails gem“friendly_id”:如何在创建对象之前获得 slug 的实时预览【英文标题】:Rails gem "friendly_id": How to get a live preview of the slug, before its object is created 【发布时间】:2013-12-27 00:32:30 【问题描述】:使用 Rails gem“friendly_id”,是否可以获得要创建的 slug 的“实时预览”?在保存对象之前,即(并在使用 ajax 请求键入时返回)?
如果有,怎么做?
【问题讨论】:
委员会必须询问您是否阅读过源代码、查看过自动化测试、调试到.save()
调用等...
被告的知识可能没有陪审团要求的那么先进,但他辩称:无罪。
【参考方案1】:
FriendyId作者在这里。
FriendlyId 在内部使用私有 set_slug
来执行此操作。此方法通过before_validation
回调调用。如果由于某种原因你不想调用valid?
,你可以通过send
调用set_slug
方法,或者在你的模型中定义一个调用它的方法:
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
字段的验证,然后您将该字段用作 slug 的基础,那么您正在预览一个实际上永远不会生成的 slug。
【讨论】:
FriendyId作者友善! :)【参考方案2】:根据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
无关。但这一切都让我想知道——因为你向用户展示了 slug——friendly_id
是否会让你像高端博客那样编辑 slug。
您可能必须先致电valid?
。
【讨论】:
谢谢 - 不幸的是,调用Article.new(title: "A new article").slug
之类的返回 nil...
您的解决方案是正确的(它返回 nil b/c 我的模型的验证失败了 b/c 我只将生成 slug 所需的属性的一个值传递给它)。所以,我必须使所有验证有条件,即validates :name, unless: :on_the_fly
,然后添加到模型attr_accessor :on_the_fly
并为其添加一个true
值,每次用户ajax-submits their value-to-be-slugged . (另一方面,这似乎并不安全,因为它允许任何人绕过验证。)
Tx 但该解决方案很糟糕。 Rails 验证很糟糕,因为验证属于表单,而不是模型。 (例如,不同的用户,看到不同的表单,可能会遇到不同的验证。)所以friendly_id 不应该需要.valid?调用传递只是为了生成一个 slug。
调用 Article.new(title: "A new article").slug
返回 nil,因为您没有调用 valid?
,因此从未生成 slug。验证对于 slug 生成实际上很重要,因为在许多情况下,slugging 方法的输入来自具有验证的字段,因此它绝对应该是验证过程的一部分。如果您从没有任何相关验证的输入中生成 slug,您可以按照我在此处的回答中描述的那样解决这个问题。
点。我应该更仔细地分离为什么 Rails 验证与为什么友好 ID 需要它们。以上是关于Rails gem“friendly_id”:如何在创建对象之前获得 slug 的实时预览的主要内容,如果未能解决你的问题,请参考以下文章
更新时删除旧的friendly_id gem slug [关闭]