Matrix
Matrix

Reputation: 3369

add dynamic route from rails database model?

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)

Upvotes: 0

Views: 70

Answers (2)

Bijendra
Bijendra

Reputation: 10015

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

Upvotes: 2

fidato
fidato

Reputation: 719

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.

Upvotes: 0

Related Questions