所以我最近通过添加一些Constraint类来整理Rails应用程序中的很多路由约束。大多数情况下,它已经很好地模块化、枯燥、易懂,所以我可能会在未来的开发中坚持使用这种模式。
我想知道从Constraint类中查询Active Record数据是否是一种“坏习惯”。例如,考虑以下类:
class CategoryConstraint
include DisplayConstraintHelper
def initialize
@names = Category.table_exists? ? Category.pluck(:name) : []
end
def matches?(request)
@names.include?(request.path_parameters[:category]) && display_matches?(request)
end
end
字符串
今天我发现我需要在上面的initialize
方法中使用table_exists?
,因为每次我运行rake任务时都会调用我的路由- * 比如设置开发数据库 *。如果数据库还不存在,而应用程序已经加载,则pluck
调用会抛出错误,因为表还不存在。
虽然调用table_exists?
可能不昂贵,但我很担心它会在生产中为每一个请求调用,当应用程序启动后,表不存在的机会。这让我开始怀疑使用Active Record表中的数据创建路由约束是否是一个坏主意。
我确实希望我的路由限制在这些值,虽然,值可以根据网站内容管理而改变(所以硬编码是愚蠢的)。我希望用户得到一个404时,他们使用一个无效的类别名称,而不是我的网站加载正常,并说“对不起,没有项目的类别 XYZ。”因此,我坚持的问题,需要这个table_exists?
调用,为初始的prod部署,为新的开发人员设置和环境第一次,并为任何人下降和设置一个新的数据库的网站。
这看起来像一个坏习惯吗?如果我想让应用程序在数据库未设置时按预期运行,这是否只是我不得不忍受的事情?
有人知道更好的替代方案吗?
2条答案
按热度按时间vecaoik11#
我在应用程序中有这样的限制:
字符串
在这个作用域内,我有一个路由globbing,所以除了使用这个约束,我不能做任何其他事情,因为slugs是由用户创建的动态资源。
我认为这是一个解决问题的工具,所以如果它是你知识最高的更好的选择,那就用它吧!
从所有这些,我明白你的应用程序需要数据库,那么你怎么能指望你的应用程序没有数据库也能正常工作呢?
vvppvyoh2#
问题更可能是从构造函数(
def initialize
)中进行数据库查询,该构造函数在定义路由时被调用。Kadu的答案应该可以正常工作,因为他的db查询是在lambda中进行的,只有当请求传入时才会调用lambda。
如果你可以在每个匹配请求上调用
Category.all.pluck(:name)
,那么你可以在matches?
方法中使用相同的约束类:字符串
如果您不需要内存中的所有名字,您最好使用以下方法:
型
如果你的目标是在内存中缓存所有的名字,这样你就不用在每次调用中都进行查询,你可以在类级别延迟赋值:
型
至于在约束中是否可以接受ActiveRecord查询-是的,我认为这是完全可以接受的,并且对于管理员特定的路由来说是个好主意。只是要注意只在
#matches?
或#call
方法中执行查询,这样它就发生在请求生命周期中。