gpt4 book ai didi

ruby-on-rails - Rails 验证以确保用户名不会与现有路由冲突?

转载 作者:行者123 更新时间:2023-12-04 12:12:06 24 4
gpt4 key购买 nike

我想确保用户无法创建与我现有路由冲突的用户名。我还希望能够拒绝我可能定义的 future 路线。我正在考虑像这样完成这个:

在模型中:

class User < ActiveRecord::Base
@@invalid_usernames = %w()

cattr_accessor :invalid_usernames

validates :username, :exclusion { :in => @@invalid_usernames }
end

在一些初始化程序中:
User.invalid_usernames += Rails.application.routes.routes.map(&:path).join("\n").scan(/\s\/(\w+)/).flatten.compact.uniq

这是“Rails方式”吗?有没有更好的办法?

最佳答案

这是我自己的答案,测试并使用 Rails 3.1.3 和 Ruby 1.9.3

应用程序/模型/user.rb

class User < ActiveRecord::Base
class_attribute :invalid_usernames
self.invalid_usernames = Set.new %w()

validates :username, presence: true,
uniqueness: { case_sensitive: false },
exclusion: { in: lambda { self.invalid_usernames }}
end

配置/应用程序.rb
[:after_initialize, :to_prepare].each do |hook|
config.send(hook) do
User.invalid_usernames += Rails.application.routes.routes.map(&:path).join("\n").scan(/\s\/(\w+)/).flatten.compact.uniq
end
end

笔记

我最初尝试设置 User.invalid_usernames期间 after_initialize但发现需要在 to_prepare期间设置(即在开发模式中的每个请求之前,以及在生产模式中的第一个请求之前),因为模型在开发中在每个请求之前重新加载并且原始设置丢失。

然而我也在设置 User.invalid_usernames期间 after_initialize因为在 to_prepare 期间路线似乎不可用在测试环境中运行时。我为此尝试的另一种解决方法是在 to_prepare 期间强制加载路由,它确实有效。 :
config.to_prepare do
Rails.application.reload_routes!
User.invalid_usernames += Rails.application.routes.routes.map(&:path).join("\n").scan(/\s\/(\w+)/).flatten.compact.uniq
end

我喜欢这个,因为它很干而且很容易阅读。但是我对每次请求都重新加载路由持谨慎态度,即使它只是处于开发模式。如果这意味着我完全理解影响,我宁愿使用更难阅读的东西。开放批评!

我也弃用了 cattr_accessorclass_attribute当我发现前者适用于整个类层次结构时(即在子类上更改其值会影响父类(super class))

我也选择使用 SetUser.invalid_usernames而不是数组,因为不需要存储和与欺骗进行比较,这是一个透明的变化。

我也更改为 Ruby 1.9 哈希语法(:

关于ruby-on-rails - Rails 验证以确保用户名不会与现有路由冲突?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8706329/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com