frank
frank

Reputation: 1303

Avoid custom route duplication for Single Table Inheritance

I have a couple of types of Users (Mover and Movee) created using Simple Table Inheritance. I am following a similar approach of passing in type in my routes as STI, one controller. But I find myself redefining the same custom routes in the base class and two subclasses.

Here is how the models look:

User
    name
    email
    address

Movee < User
    has_many: moves

Mover < User

user.rb

     def edit
     end

     def edit_address
     end

     def update_address
       @user.update(user_address_params)
       @user.type = "Mover"
       @user.save
     end

     def update
       @user.update(user_params)
     end

     def user_params
       params.require(params[:type].to_sym).permit(
            :first_name, :last_name,
            :type)
     end

     def user_address_params
       params.require(params[:type].to_sym).permit(:address)
     end

The params hash for the edit_address action will look like

{
  movee: { address:  "some address"} 
  type: "movee"
}

In the navbar, I am pointing to a generic edit user path:

<li><a href="<%= edit_address_user_path(current_user) %>"> Update Address</a></li>

Now the routes duplication:

routes.rb

  resources :shmoovee,  path: :users, controller: :users, type: "shmoovee" do
    member do
      get :edit_address
      patch :update_address
    end
  end

  resources :shmoover,  path: :users, controller: :users, type: "shmoover" do
    member do
      get :edit_address
      patch :update_address
    end
  end

  resources :users do
    member do
      get :edit_address
      patch :update_address
    end
  end

Question: Is there a way around the route duplications? I need the subclass routes in order to pass in the type to resolve the strong params, but I also need the base class route in order to have the generic route helper edit_address_user_path used in the view.

Upvotes: 0

Views: 61

Answers (1)

frank
frank

Reputation: 1303

This is the routes I ended up with using routing-concerns:

  concern :addressable do
    member do
      get :edit_address
      patch :update_address
    end
  end

  resources :shmoovee,  path: :users, controller: :users, type: "shmoovee", concerns: :addressable 

  resources :shmoover,  path: :users, controller: :users, type: "shmoover", concerns: :addressable 

  resources :users do
    concerns :addressable
    # other user routes
  end

Upvotes: 1

Related Questions