Rewrite Routes in Rails Engine

Introduction

Rails Engine is used when you want to provide the functionality of the same application in multiple projects, right?

Is it device in the famous gem?

Although it is such a Rails Engine, there are times when you want to add unique functions in a higher-level application.

This time we will focus on Routes

Let's overwrite and add Rails Engine Routes in the upper application

Rails Routes Defines the routing of the application

routes.rb


Rails.application.routes.draw do
  resources :posts
end

Rails Engine looks like this

routes.rb


MyEngine::Engine.routes.draw do
  resources :users
end

draw Let's see what this draw method is doing

https://github.com/rails/rails/blob/66a4cf4bbc0651b995646ad86aa76f5634da49c5/actionpack/lib/action_dispatch/routing/route_set.rb#L407-L412

rails/actionpack/lib/action_dispatch/routing/route_set.rb


def draw(&block)
  clear! unless @disable_clear_and_finalize
  eval_block(block)
  finalize! unless @disable_clear_and_finalize
  nil
end

Something is cleared !, block is expanded, and finalize!

clear! See what clear! is doing

https://github.com/rails/rails/blob/66a4cf4bbc0651b995646ad86aa76f5634da49c5/actionpack/lib/action_dispatch/routing/route_set.rb#L438-L445

rails/actionpack/lib/action_dispatch/routing/route_set.rb


def clear!
  @finalized = false
  named_routes.clear
  set.clear
  formatter.clear
  @polymorphic_mappings.clear
  @prepend.each { |blk| eval_block(blk) }
end

Somehow you are expanding @prepend

Where is @prepend set?

rails/actionpack/lib/action_dispatch/routing/route_set.rb


def prepend(&block)
  @prepend << block
end

You can see that the block of the method is expanded by prepend

This means that the routes defined in prepend will be plugged in front of the one defined in the application's draw.

Rails routes are matched from top to bottom, allowing you to override predefined routes.

finalize! Let's see what finalize! Is doing

https://github.com/rails/rails/blob/66a4cf4bbc0651b995646ad86aa76f5634da49c5/actionpack/lib/action_dispatch/routing/route_set.rb#L432-L436

rails/actionpack/lib/action_dispatch/routing/route_set.rb


def finalize!
  return if @finalized
  @append.each { |blk| eval_block(blk) }
  @finalized = true
end

You are expanding @append

Where is @append set?

rails/actionpack/lib/action_dispatch/routing/route_set.rb


def append(&block)
  @append << block
end

You can see that the block of the method called append is expanded

This means that the routes defined in append will be plugged in after being defined in the application's draw.

So you can simply add Routes, but the routing defined in your application will take precedence.

Override Rails Engine Routes

Let's overwrite the Engine routes

Such a routing is defined and I want to overwrite the nested routing!

routes.rb


MyEngine::Engine.routes.draw do
  resources :users
end

Since it is an overwrite, it is defined using prepend

The use case where you want to nest like this is when you want to use the engine namespace.

config/initializers/my_engine_routes.rb


MyEngine::Engine.routes.prepend do
  resources :users do
    resources: posts
  end
end

If you want to add it, define it using append

config/initializers/my_engine_routes.rb


MyEngine::Engine.routes.append do
  resources: posts
end

Summary

This time, I wrote how to overwrite and add Routes of Rilas Engine while looking at the Rails code.

Of course, you can do the same with higher-level apps

You can also use prepend, append to split the bloated routes file.

Recommended Posts

Rewrite Routes in Rails Engine
Group_by in Rails
Adding columns in Rails
Disable turbolinks in Rails
CSRF measures in Rails
^, $ in Rails regular expression
Use images in Rails
Understand migration in rails
Split routes.rb in Rails6
Implement markdown in Rails
Get UserAgent in [Rails] controller
Implement application function in Rails
Declarative transaction in Rails #ginzarb
Implement follow function in Rails
Japaneseize using i18n with Rails
Implement LTI authentication in Rails
Error in rails db: migrate
Gem often used in Rails
Display Flash messages in Rails
View monthly calendar in Rails
Implement import process in Rails
Output Rails Routes as csv
Rails: Capture regular expressions in emails!
[Rails] Keyword search in multiple tables
[Rails] Session timeout setting in devise
Enable jQuery and Bootstrap in Rails 6 (Rails 6)
[Rails] How to write in Japanese
[Rails] Unexpected validation error in devise
About the symbol <%%> in Rails erb
Explanation of the order of rails routes
[Rails] Use cookies in API mode
Implement simple login function in Rails
Create a new app in Rails
Ruby on Rails Japanese-English support i18n
Implement a contact form in Rails
Remove "assets" and "turbolinks" in "Rails6".
CRUD features and MVC in Rails
How to introduce jQuery in Rails 6
First pagination feature added in rails
Data is not registered in Rails.
[Rails 6] Customize Bootstrap in Rails + Bootstrap 5.0.0-alpha environment
Implement CSV download function in Rails
Ruby methods often used in Rails
How to install Swiper in Rails