添加Rails数据库模型中的动态路由?

huangapple go评论56阅读模式
英文:

add dynamic route from rails database model?

问题

我尝试从数据库中动态添加路由,使用模型 ActiveRecord:

我尝试了以下方法(在 Rails 5 中使用):

Rails.application.routes.draw do
  router = self
  Var.find_by(name: 'pages').value.split(',').each do |page|
    router.get "/#{page}", to: 'application#page', as: page
  end
end

但当我尝试启动 Rails 服务器时,出现了错误:

rescue in mysql2_connection: 未知数据库 'dale'(ActiveRecord::NoDatabaseError)

英文:

How can I add dynamic route from database, using model activeRecord :

I try : (using Rails 5)

Rails.application.routes.draw do
  router = self
  Var.find_by(name: 'pages').value.split(',').each do |page|
    router.get "/#{page}", to: 'application#page', as: page
  end
end

but I have an error when I try start rails server :

> `rescue in mysql2_connection': Unknown database 'dale' (ActiveRecord::NoDatabaseError)

答案1

得分: 2

可以将访问数据库的代码移动到初始化块中。

Rails.application.routes.draw do
router = self
Rails.application.config.after_initialize do
Var.find_by(name: 'pages').value.split(',').each do |page|
router.get "/#{page}", to: 'application#page', as: page
end
end
end

不能保证你的初始化器会在所有 gem 初始化器之后运行,因此依赖于给定 gem 已被初始化的任何初始化代码应放在 config.after_initialize 块中。

Rails 有 5 个可以挂钩的初始化事件(按照它们运行的顺序列出):更多详情请参考 Rails 文档中的初始化事件

英文:

You can move the code that access the db to initialize block.

Rails.application.routes.draw do
  router = self
  Rails.application.config.after_initialize do
	  Var.find_by(name: 'pages').value.split(',').each do |page|
	    router.get "/#{page}", to: 'application#page', as: page
	  end
  end
end

There is no guarantee that your initializers will run after all the gem initializers, so any initialization code that depends on a given gem having been initialized should go into a config.after_initialize block.

Rails has 5 initialization events which can be hooked into (listed in the order that they are run): Further details in Rails documentation initialization events

答案2

得分: 0

你遇到的问题是因为 Var.find_by(name: 'pages') 试图运行 ActiveRecord 查询,但 Rails.application.routes.draw 块在应用程序启动时执行,而在建立数据库连接之前执行。

为了解决这个问题,你可以将定义动态路由的逻辑移到一个控制器操作中,在建立数据库连接后运行它。然后,在操作中使用 redirect_to 来重定向到适当的路由:

# 在你的控制器中
def pages
  page = params[:page]
  redirect_to "/#{page}"
end

# 在你的路由文件中
Rails.application.routes.draw do
  get 'pages', to: 'application#pages'
  Var.find_by(name: 'pages').value.split(',').each do |page|
    get "/#{page}", to: 'application#page', as: page
  end
end

通过这种方式,当请求 /pages URL 时,将运行 pages 操作,并根据页面参数重定向到适当的路由。

希望这对你有所帮助。

英文:

The issue you're encountering is because Var.find_by(name: 'pages') is trying to run ActiveRecord query, but the Rails.application.routes.draw block is executed when the application starts and before the database connection is established.

To solve this, you can move the logic for defining the dynamic routes to a controller action, which will run after the database connection is established. You can then use redirect_to in the action to redirect to the appropriate route:

# in your controller
def pages
  page = params[:page]
  redirect_to "/#{page}"
end

# in your routes file
Rails.application.routes.draw do
  get 'pages', to: 'application#pages'
  Var.find_by(name: 'pages').value.split(',').each do |page|
    get "/#{page}", to: 'application#page', as: page
  end
end

By this way, when a request is made to the /pages URL, the pages action will run and redirect to the appropriate route based on the page parameter.

I hope this helps.

huangapple
  • 本文由 发表于 2023年2月10日 15:06:34
  • 转载请务必保留本文链接:https://go.coder-hub.com/75407906.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定