Reputation: 1303
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.
Upvotes: 0
Views: 61
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