0

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
  • The moves under Movee will have its set of addresses. The Mover will have an address as well as defined in the User model. When the User first gets created, they just need the name and email, and the default user is of type Movee.

  • Then you can go to a page to update your address, this will turn you from a Movee to a Mover.

  • A Mover can re-update the address. I have defined a custom edit_address action in the user model, since you can update the address as both a Movee (to turn yourself into a Mover), or as a Mover (if you need to re-update your the address).

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.

Community
  • 1
  • 1
frank
  • 1,283
  • 1
  • 19
  • 39
  • Check out the routing concerns, it may come in handy or it may do what you actually want to achieve http://edgeguides.rubyonrails.org/routing.html#routing-concerns – kurenn Mar 26 '17 at 20:38
  • @kurenn, thanks for pointing me to routing-concerns, I can refactor the common routes with it and reduce the duplication. – frank Mar 29 '17 at 04:45

1 Answers1

1

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
frank
  • 1,283
  • 1
  • 19
  • 39