I have a Ruby on Rails application that can generate "roles" for actors in movies; the idea is that if a user looks at a movie detail page, they can click "add role", and the same if they look at an actor detail page. Once the role is generated, I would like to redirect back to where they came from - the movie detail page or the actor detail page... so in the controller's "create" and "update" method, the redirect_to should either be movie_path(id) or actor_path(id). How do I keep the "origin" persistent, i. e. how do I remember whether the user came from movie detail or from actor detail (and the id, respectively)?
CodePudding user response:
I would setup separate nested routes and just use inheritance, mixins and partials to avoid duplication:
resources :movies do
resources :roles, module: :movies, only: :create
end
resources :actors do
resources :roles, module: :actors, only: :create
end
class RolesController < ApplicationController
before_action :set_parent
def create
@role = @parent.roles.create(role_params)
if @role.save
redirect_to @parent
else
render :new
end
end
private
# guesses the name based on the module nesting
# assumes that you are using Rails 6
# see https://stackoverflow.com/questions/133357/how-do-you-find-the-namespace-module-name-programmatically-in-ruby-on-rails
def parent_class
module_parent.name.singularize.constantize
end
def set_parent
parent_class.find(param_key)
end
def param_key
parent_class.model_name.param_key "_id"
end
def role_params
params.require(:role)
.permit(:foo, :bar, :baz)
end
end
module Movies
class RolesController < ::RolesController
end
end
module Actors
class RolesController < ::RolesController
end
end
# roles/_form.html.erb
<%= form_with(model: [parent, role]) do |form| %>
# ...
<% end %>