Add Show User Link to Navbar Devise - ruby-on-rails

In a class, I'm built a Pintrest style app, and I recently set up a show action for my users. The link works fine on the individual pins, but when I try to add the users#show link to the Navbar called "Profile" it does not navigate anywhere. The Profile link should navigate to users#show, but the URL is showing for Profile is my pins#index which is my root route. Here are the links in my Navbar under _header.html.erb.
<div class="nav-collapse collapse">
<ul class="nav pull-right">
<% if user_signed_in? %>
<li><%= link_to "Add Trip", new_pin_path %></li>
<li><%= link_to "About", about_path %></li>
<li><%= link_to "Profile", #user %></li>
<li><%= link_to "Logout", destroy_user_session_path, method: :delete %></li>
<% else %>
<li><%= link_to "About", about_path%></li>
<li><%= link_to "Login", new_user_session_path %></li>
<% end %>
</ul>
</div>
Here is my users_controller.rb
class UsersController < ApplicationController
def show
#user = User.find(params[:id])
#pins = #user.pins.page(params[:page]).per_page(20)
end
end
But the show user link on the pins in _pin.html.erb which is rendered in my pins#index works fine.
<div class="box">
<p class= "description">
<%= pin.description %>
</p>
<%= link_to (image_tag pin.image(:medium)), pin %>
<p class= "author">
<strong>
Posted by <%= link_to pin.user.name, pin.user %>
</strong>
</p>
</div>
Lastly, if I copy the same link that is in _pin.html.erb <%= link_to pin.user.name, pin.user %> to the Navbar, I get undefined local variable or methodpin' for #<#:0x00000100c82520>`.
Here is my routes.rb incase that helps.
devise_for :users
match 'users/:id' => 'users#show', as: :user

You need to use current_user instead of #user, since #user will be nil in most cases (except on your users#show page.
It might also be a good idea to create a /profile route that always loads the current user.

Related

Ruby on rails - user is nil after creating a session and redirecting home

I am building a rails app.
I am using devise to handle authentication
If the user is an admin, he or she should be able to see a link in the navbar that redirects to the whole list of profiles (for testing purposes)
<% if !user_signed_in? %>
<li class="nav-item">
<%= link_to "Sign up", new_user_registration_path, class: "nav-link" %>
</li>
<li class="nav-item">
<%= link_to "Log in", new_user_session_path, class: "nav-link" %>
</li>
<% else %>
<li class="nav-item">
<%= link_to "Log out", destroy_user_session_path, method: :delete, class: "nav-link" %>
</li>
<% if !#user.nil? && #user.admin? %>
<li class="nav-item">
<%= link_to "See all profiles", profiles_path, class: "nav-link" %>
</li>
<% end %>
<li class="nav-item">
<%= link_to "My profile", user_profile_path(current_user, current_user.user_profile), class: "nav-link" %>
</li>
<% end %>
However, said link only shows after going inside the my profile link. I did a raise in the UserProfiles controller to see what's going on and apparently the user is nil in the homepage even after logging in, hence the reason why the see all profiles link is not appearing
My guess is that I am missing an instance variable that provides the user id somewhere, (pages controller perhaps?) I don't have a users controller or user sessions controller yet. Basically, I don't understand why is the user nil after logging in and why is the log out link showing up without a user?
UserProfiles controller
class UserProfilesController < ApplicationController
before_action :set_user, only: [:index, :show]
def index
#user_profiles = UserProfile.all
end
def show
#user_profile = UserProfile.find(params[:id])
#user_profile.user = #user
end
private
def set_user
#user = current_user
end
end
Thanks for your help
You are not passing #user from the controller so cannot use in the view.
You should change your code to
<% if !#user_profile.user.nil? && #user_profile.user.admin? %>
<li class="nav-item">
<%= link_to "See all profiles", profiles_path, class: "nav-link" %>
</li>
<% end %>

Linking to basket/cart in ruby on rails

I have a menu in my header that has a show basket and a login button, each work when the code is placed in separately but not when both lines are in the file.
I'm using devise for the users.
Is there a better way to link to the current basket?
<li><%= link_to basket_path(#basket.id) do %>
<%= image_tag "/assets/viewBasket.png" %>
</li>
<% end %>
<% if signed_in? %>
<li><%= link_to edit_user_registration_path do%>
<%= image_tag"/assets/my_account.png" %></a></li>
<% end %>
<li><%= link_to destroy_user_session_path do%>
<%= image_tag"/assets/logout.png" %></li>
<%end%>
<% else %>
<li><%= link_to new_user_session_path do%>
<%= image_tag"/assets/loginRegisterBtn.png" %></li>
<% end%>
<% end %>
If I run on its own this works but not with the code after.
<li><%= link_to basket_path(#basket.id) do %>
<%= image_tag "/assets/viewBasket.png" %></li>
<% end %>
I think its to do with the way the current basket is set with the session id in the current_basket model.
module CurrentBasket
private
def set_basket
#basket = Basket.find(session[:basket_id])
rescue ActiveRecord::RecordNotFound
#basket = Basket.create
session[:basket_id] = #basket.id
end
end
The closing of <li> must be after the end of the link, like this:
<li>
<%= link_to basket_path(#basket.id) do %>
<%= image_tag "/assets/viewBasket.png" %>
<% end %>
</li>
I used the answer above which helped with one issue, however, I found that I had defined only the shop and index page. Removing this and it now works.
include CurrentBasket
before_action :set_basket, only: [:index, :shop]

rails instead link_to - render it

I have controller for home, about, contact
I created navigation for that
<li><%= link_to 'Home' , homepage_path %></li>
<li><%= link_to 'About' , about_path %></li>
<li><%= link_to 'Contact' , contact_path %></li>
And it's working well, But now I created a navigation for my admin panel and I wanted to make it more organized so I did it with partials:
(on my /views/admin/index.html.erb )
<ul class="admin-nav">
<li rel="posts">Posts</li>
<li rel="pages">Pages</li>
</ul>
<div class="posts panel">
<%= render "posts/index" %>
</div>
<div class="pages panel">
<%= render "pages/index" %>
</div>
But now let's say I'm clicking on the posts button on my admin panel, It no longer need to go to the posts_path, it needs to render it, Can I do that?

How to make links for index and show actions work in partial views

I am using a partial to render a nav bar from the layouts folder in all my pages, and within the nav bar I have links to actions such as index and show from a GradesController. I understand that in order for the links to work I must call them in that page's action in the controller as such:
def home
#grades = Grade.all
end
However as these links exist within a partial view which doesn't have a corresponding controller, how can I make these links work without getting a NoMethodError?
layouts/_navbar.html.erb
<div class="main_nav_color">
<div class="wrapper">
<header id="main_header" class="cf">
arabecademy
<nav>
<ul>
<li>
<%= link_to "#" do %>
Grade<span class="glyphicon glyphicon-chevron-down"></span>
<% end %>
<ul>
<% #grades.each do |grade| %>
<li><%= link_to "Grade" + grade.grade_number, grade_courses_path(grade, #course) %></li>
<% end %>
</ul>
</li>
<li>About</li>
<li>Contact</li>
<% if student_signed_in? %>
<li><%= link_to "Log Out", destroy_student_session_path, method: :delete %></li>
<li><%= link_to "Accout Settings", edit_student_registration_path %></li>
<% else %>
<li><%= link_to "Log in", new_student_session_path %></li>
<li><%= link_to "Sign Up", new_student_registration_path, :class => "button_sm button_orange" %></li>
<% end %>
</ul>
</nav>
</header>
</div>
</div>
To get #grades set all the time, you can add a before_filter in ApplicationController like this:
class ApplicationController
before_action :load_grades
def load_grades
#grades = Grade.all
end
end
This will make sure that every single controller action has #grades set in addition to whatever the action itself does. Your partial should be able to pick up #grades wherever you display it now.

Where should I set the current_user so I don't get a missing key error?

My question assumes a specific answer but it may not but accurate.
I've created a route:
get 'users/:id/groups/' => 'users#groups', as: "my_groups"
but when I go to access this path, conditionally, in a view, i get an exception:
ActionController::UrlGenerationError at /
No route matches {:controller=>"users", :action=>"groups"} missing required keys: [:id]
Here is the partial with the offending line:
<% if user_signed_in? %>
<li id="groups-menu" class="dropdown">
<a href="#" class="dropdown-toggle" data-toggle="dropdown">
Groups <b class="caret"></b>
</a>
<ul class="dropdown-menu">
#offending line:
<li><%= link_to 'My Groups', my_groups_path %></li>
<li><%= link_to 'Create a Group', new_group_path %></li>
</ul>
</li>
<li><%= link_to 'Logout', destroy_user_session_path, :method=>'delete' %></li>
<% else %>
<li><%= link_to 'Login', new_user_session_path %></li>
<% end %>
<% if user_signed_in? %>
<li><%= link_to 'Edit account', edit_user_registration_path %></li>
<% end %>
<% if user_signed_in? %>
<% if current_user.has_role? :admin %>
<li><%= link_to 'Admin', users_path %></li>
<% end %>
<% end %>
it seems that there is no current_user set, perhaps?
It's unclear how this could break if the user_signed_in? method is working.
You need to pass in the :id parameter to the url helper function
<li><%= link_to 'My Groups', my_groups_path(current_user) %></li>

Resources