Home > Software design >  How to route actions based on object class with namespaced controllers in Rails 5.2?
How to route actions based on object class with namespaced controllers in Rails 5.2?

Time:10-07

I am refactoring my application so that users are now managed in a dedicated Administration namespace. I did the following:

routes.rb

  namespace :administration do
    get 'users',           to: "/administration/users#index"
    resources :users
    resources :groups
  end

The Users and Groups controller are now in the app/controllers/administration folder. They are defined as Administration::UsersController and Administration::GroupsController. The models are not namespaced.

The related links are now based on administration_users_path and administration_groups_path.

I use some partials for hamonised layout. One of them diplays Edit and Delete buttons, where this_object represents the instance passed to the locals:

_object_actions.erb

<% if this_object.is_active %>

  <%= link_to [ :edit, this_object], method: :get, class: "mat-flat-button mat-button-base mat-primary" do%>
    <span class="fa fa-edit"></span>
    <%= t("Edit") %>
  <% end %>

  <%= link_to this_object, data: { confirm: t("Sure") }, method: :delete, class: "mat-flat-button mat-button-base mat-warn" do%>
    <span class="fa fa-trash"></span>
    <%= t("Destroy") %>
  <% end %>

<% else %>

  <%= link_to [ :activate, this_object], method: :post, class: "mat-stroked-button mat-button-base" do%>
    <span class="fa fa-trash-restore"></span>
    <%= t("Recall") %>
  <% end %>

<% end %>

But coming to to Users and Groups, the path to actions is not properly built. I would need to build the URL such as /administration/users/1/edit, but it actually is /users/1/edit.

How can I make sure to build the correct URL for this purpose?

CodePudding user response:

You can specify the desired route for each link_to

<%= link_to "Edit", edit_administration_user_path(this_object) %>

CodePudding user response:

Thanks to this post Rails using link to with namespaced routes, I undestood that it is possible to add more parameters to the link_to method to build the actual link.

To call namespaced controller methods, I added the following to the links:

<%# Check if the parent is a module defined as Namespace. If not (Object) then display default link %>
<% namespace = controller.class.parent.name == 'Object' ? 
   nil : 
   controller.class.parent.name.downcase %>

<% if this_object.is_active %>
  <%= link_to [ :edit, namespace, this_object], 
      method: :get, 
      class: "mat-flat-button mat-button-base mat-primary" do %>
      <span class="fa fa-edit"></span>
      <%= t("Edit") %>
  <% end %>

  <%= link_to [namespace, this_object], 
      data: { confirm: t("Sure") }, 
      method: :delete, 
      class: "mat-flat-button mat-button-base mat-warn" do %>
      <span class="fa fa-trash"></span>
      <%= t("Destroy") %>
  <% end %>

<% else %>

  <%= link_to [ :activate,  namespace, this_object], 
      method: :post, 
      class: "mat-stroked-button mat-button-base" do %>
      <span class="fa fa-trash-restore"></span>
      <%= t("Recall") %>
  <% end %>

<% end %>
  • Related