gpt4 book ai didi

ruby-on-rails - 基于数据库模型的动态 Rails 路由

转载 作者:数据小太阳 更新时间:2023-10-29 07:04:40 26 4
gpt4 key购买 nike

所以我正在构建一个需要基于两种不同类型的路由的 Rails 站点

我有一个语言模型和一个类别模型

所以我需要能够转到语言路径/ruby 以查看顶级 ruby​​ 资源,还可以转到/books 以查看所有语言的顶级书籍

我试过这样的路线

get '/:language', to: "top_voted#language"
get '/:category', to: "top_voted#category"

问题是逻辑无法弄清楚两者之间的区别,导致后端发生一些冲突

这个我也试过

Language.all.each do |language|
get "#{language.name}", to: "top_voted#language", :language => language.name
end

Category.all.each do |category|
get "#{category.name}", to: "top_voted#category", :category => category.name
end

但是问题是我们部署的 Heroku 不允许在路由中调用数据库。有没有更简单的方法来做到这一点?我们需要能够以某种方式动态生成这些路由。

最佳答案

使用路由约束可以很好地解决该问题。

使用路由约束

作为rails routing guide建议,您可以通过检查路径是否属于语言或类别的方式来定义路由约束。

# config/routes.rb
# ...
get ':language', to: 'top_voted#language', constraints: lambda { |request| Language.where(name: request[:language]).any? }
get ':category', to: 'top_voted#category', constraints: lambda { |request| Category.where(name: request[:category]).any? }

顺序定义了优先级。在上面的示例中,如果一种语言和一个类别具有相同的名称,则该语言获胜,因为它的路由定义在类别路由之上。

使用永久链接模型

如果您想确保所有路径都是唯一的,一个简单的方法是定义一个 Permalink 模型并在那里使用验证。

生成数据库表:rails generate model Permalink path:string reference_type:string reference_id:integer && rails db:migrate

并在模型中定义验证:

class Permalink < ApplicationRecord
belongs_to :reference, polymorphic: true
validates :path, presence: true, uniqueness: true

end

并将其与其他对象类型相关联:

class Language < ApplicationRecord
has_many :permalinks, as: :reference, dependent: :destroy

end

这还允许您为记录定义多个永久链接路径。

rails_category.permalinks.create path: 'rails'
rails_category.permalinks.create path: 'ruby-on-rails'

使用此解决方案,路由文件必须如下所示:

# config/routes.rb
# ...
get ':language', to: 'top_voted#language', constraints: lambda { |request| Permalink.where(reference_type: 'Language', path: request[:language]).any? }
get ':category', to: 'top_voted#category', constraints: lambda { |request| Permalink.where(reference_type: 'Category', path: request[:category]).any? }

并且,作为在 Controller 中使用 cancan gem 和 load_and_authorize_resource 的其他用户的旁注:您必须在调用 load_and_authorize_resource 之前通过永久链接加载记录:

class Category < ApplicationRecord
before_action :find_resource_by_permalink, only: :show
load_and_authorize_resource

private

def find_resource_by_permalink
@category ||= Permalink.find_by(path: params[:category]).try(:reference)
end
end

关于ruby-on-rails - 基于数据库模型的动态 Rails 路由,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22236619/

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