使用 friendly_id gem 有条件地重置 slug
Conditionally reset slug using friendly_id gem
我的应用程序使用 friendly_id gem:
以通常的方式分配 slug
class Organization < ApplicationRecord
extend FriendlyId
friendly_id :name, use: :slugged
strip_attributes
end
当用户更改 organization.name 时,默认情况下 slug 不会更改。但我想给用户一个选项来重置 slug 以匹配名称。
从控制台看,这很简单:
>> organization.update(slug: nil)
Friendly_id 使用 before_validate 钩子跳入并生成一个新的 slug。但是,如果我尝试使用 OrganizationsController#update 方法将 slug
设置为 nil
,它不起作用:
Started PATCH "/organizations/slo-mo-100?organization%5Bslug%5D=" for 127.0.0.1 at 2017-10-10 16:37:30 -0600
Processing by OrganizationsController#update as HTML
Parameters: {"organization"=>{"slug"=>""}, "id"=>"slo-mo-100"}
Organization Load (0.5ms) SELECT "organizations".* FROM "organizations" WHERE "organizations"."slug" = ORDER BY "organizations"."id" ASC LIMIT [["slug", "slo-mo-100"], ["LIMIT", 1]]
(0.3ms) BEGIN
SQL (4.1ms) UPDATE "organizations" SET "slug" = , "updated_at" = WHERE "organizations"."id" = [["slug", nil], ["updated_at", "2017-10-10 22:37:30.077956"], ["id", 1]]
(0.2ms) ROLLBACK
Completed 500 Internal Server Error in 24ms (ActiveRecord: 6.2ms)
PG::NotNullViolation - ERROR: null value in column "slug" violates not-null constraint
我希望 #update 操作像控制台一样操作,即在传入值设置为 nil 时分配一个新的 slug。
事实证明解决方案非常简单。问题是更新参数通过 slug 设置为空字符串 ({"slug"=>""}
) 而不是 nil
。我正在使用 strip_attributes
gem 将空字符串转换为 nil,但是直到 friendly_id
已经检查 slug
之后 strip_attributes
才被调用] 字段是 nil
。
我通过将回调的顺序切换为在 friendly_id
之前触发 strip_attributes
解决了这个问题:
class Organization < ApplicationRecord
extend FriendlyId
strip_attributes
friendly_id :name, use: :slugged
end
我的应用程序使用 friendly_id gem:
以通常的方式分配 slugclass Organization < ApplicationRecord
extend FriendlyId
friendly_id :name, use: :slugged
strip_attributes
end
当用户更改 organization.name 时,默认情况下 slug 不会更改。但我想给用户一个选项来重置 slug 以匹配名称。
从控制台看,这很简单:
>> organization.update(slug: nil)
Friendly_id 使用 before_validate 钩子跳入并生成一个新的 slug。但是,如果我尝试使用 OrganizationsController#update 方法将 slug
设置为 nil
,它不起作用:
Started PATCH "/organizations/slo-mo-100?organization%5Bslug%5D=" for 127.0.0.1 at 2017-10-10 16:37:30 -0600
Processing by OrganizationsController#update as HTML
Parameters: {"organization"=>{"slug"=>""}, "id"=>"slo-mo-100"}
Organization Load (0.5ms) SELECT "organizations".* FROM "organizations" WHERE "organizations"."slug" = ORDER BY "organizations"."id" ASC LIMIT [["slug", "slo-mo-100"], ["LIMIT", 1]]
(0.3ms) BEGIN
SQL (4.1ms) UPDATE "organizations" SET "slug" = , "updated_at" = WHERE "organizations"."id" = [["slug", nil], ["updated_at", "2017-10-10 22:37:30.077956"], ["id", 1]]
(0.2ms) ROLLBACK
Completed 500 Internal Server Error in 24ms (ActiveRecord: 6.2ms)
PG::NotNullViolation - ERROR: null value in column "slug" violates not-null constraint
我希望 #update 操作像控制台一样操作,即在传入值设置为 nil 时分配一个新的 slug。
事实证明解决方案非常简单。问题是更新参数通过 slug 设置为空字符串 ({"slug"=>""}
) 而不是 nil
。我正在使用 strip_attributes
gem 将空字符串转换为 nil,但是直到 friendly_id
已经检查 slug
之后 strip_attributes
才被调用] 字段是 nil
。
我通过将回调的顺序切换为在 friendly_id
之前触发 strip_attributes
解决了这个问题:
class Organization < ApplicationRecord
extend FriendlyId
strip_attributes
friendly_id :name, use: :slugged
end