I am working on a rails app, where one of the tabs (the user show view) has a partial that is an inner navbar of sorts. There are three links ( match , activity , message ), each of which correspond to a different partial that is rendered to the right of the inner navbar.
Each of the partials has a corresponding route in my routes.rb file, but they are all rendered within one controller action ( user#show ). As a result, my inner navbar links alone are bringing the page to the proper route, but aren't successfully rendering the partials. To resolve this, I am checking within the view for what the end of the route is, and rendering the appropriate partial accordingly.
I imagine that there is a more ideal way to accomplish what I am looking to do, but I've had trouble figuring out what that might be.
I know that I could use separate view files instead of partials to resolve this, but for the sake of modularity, I would rather not move in that direction. Is there a better way for me to link routes to the appropriate partials?
routes.rb
Rails.application.routes.draw do
mount RailsAdmin::Engine => '/admin', as: 'rails_admin'
resources :messages
resources :replies
resources :posts
resources :organizations
resources :users
resources :sessions
resources :matches
root "welcome#index"
get "/users/:id/match", to: "users#show", as: "user_match"
get "/users/:id/activity", to: "users#show", as: "user_activity"
get "/users/:id/message", to: "users#show", as: "user_message"
end
users_controller
class UsersController < ApplicationController
skip_before_action :verify_authenticity_token, only: [:create]
def show
@user = User.find(params[:id])
end
def new
@user = User.new
end
def create
@user = User.new(user_params)
if @user.save
log_in @user
flash[:notice] = "Your account was created!"
redirect_to @user
else
flash[:alert] = @user.errors.full_messages.join(", ")
render 'new'
end
end
private
def user_params
params.require(:user).permit(:first_name, :last_name, :email, :password, :password_confirmation)
end
end
/users/show.html.erb
<div class="row">
<% if @user.id == current_user.id %>
<div class="col-md-2 justify-content-start">
<div>
<ul>
<li>
<%= link_to(user_message_path(current_user.id)) do %>
<%= fa_icon "envelope", text: "Messages" %>
<% end %>
</li>
<li>
<%= link_to(user_activity_path(current_user.id)) do %>
<%= fa_icon "comments", text: "Activity" %>
<% end %>
</li>
<li>
<%= link_to(user_match_path(current_user.id)) do %>
<%= fa_icon "handshake-o", text: "Matches" %>
<% end %>
</li>
</ul>
</div>
</div>
<% end %>
<div class="col-md-10 justify-content-center">
<% last = request.path.split('/').last%>
<% if @user.id == current_user.id %>
<% if last == "match" %>
<%= render partial: "match" %>
<% elsif last == "activity" %>
<%= render partial: "activity" %>
<% elsif last == "message" %>
<%= render partial: "message" %>
<% else %>
<%= render partial: "home"%>
<% end %>
<% else %>
<%= render partial: "home" %>
<% end %>
</div>
</div>
You have a few alternative approaches you could take, like setting each sub-page up as a new controller (UserMatchesController, etc.) and routing to them directly, or using AJAX to load the sub-sections dynamically, but your approach isn't bad. What I would do to improve on it is to make the sub-page a named segment in the route with a constraint to lock it down:
get "/users/:id/:section", to: "users#show", constraints: { section: /^(message|home|match|activity)$/ }
You can link to each section by passing that parameter as an argument:
link_to user_path(current_user.id, section: "message")
And then in your template, something like:
render partial: params[:section]
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.