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

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>

Related

How to use the `link_to_unless_current` helper to work for both current or root path?

I am setting up my navbar link_to's and I'm trying to stop a link being rendered if current_path is the same as link_path or if current path is the same as root path, as root path is defined as that same as the link path, as below:
_navbarhtml.erb
<ul class="nav navbar-nav navbar-right">
<% if user_signed_in? %>
<li><%= link_to_unless_current('My Quotes', quotes_path(current_user)) do %></li>
<% end %>
<li><%= link_to_unless_current('New Quote', new_quote_path) do %></li>
<% end %>
<li><%= link_to('My Account', edit_user_registration_path) %></li>
<li><%= link_to "Sign out", destroy_user_session_path, :method => :delete %></li>
<% else %>
<li><%= link_to('Sign in', new_user_session_path) %></li>
<li><%= link_to('Sign up', new_user_registration_path) %></li>
<% end %>
</li>
routes.rb
root 'quotes#new'
Any neat suggestions as to how to nicely write this?
You can try current_page?. Create a helper method like so:
def link_to_unless_current(text, url, options={})
if current_page?(url)
# do something else? maybe create a text which does not have a link?
else
link_to text, url, options
end
end
Now, view will be like:
<%= link_to_unless_current('My Quotes', quotes_path(current_user)) %>
Feel free to change the name of helper method.
Thanks Surya, this is the way i got it to work in the end:
application_helper.rb
def link_to_unless_current_or_root(text, url)
if current_page?(url)
elsif current_page?(root_path)
else
link_to text, url
end
end
_navbar.html.erb
<li><%= link_to_unless_current_or_root('New Quote', new_quote_path) %></li>

Rails link with error message and current user

I have hard time coming up with an idea how to implement a link called "Add guide", that requires user to be signed in. To direct to new guide path I need to add "new_user_guide_path(#user) or "new_user_guide_path(current_user)", and adding "current_user" or #user causes an error because of being equal nil - so I don't know how to implement new method in guide controller.
PS: I used devise gem to create user model.
my header partial:
<header class="cf header2">
<h1 class="logo"><%= link_to "E-LEARN", root_path %></h1>
<nav>
<ul>
<% unless user_signed_in? %>
<li><%= link_to "Log In", new_user_session_path %></li>
<% else %>
<li><%= link_to "Dashboard", root_path %></li>
<li><%= link_to "Log Out", destroy_user_session_path, method: :delete %></li>
<li><%= link_to "Settings", edit_user_registration_path %></li>
<li><%= link_to "My Account", current_user %></li>
<% end %>
<% if user_signed_in? %>
<li><%= link_to "Add tutorial", new_user_guide_path(#user) %></li>
<% end %>
</ul>
</nav>
</header>
and routes:
Rails.application.routes.draw do
devise_for :users
resources :users, only: [:show, :index, :new] do
resources :guides
end
authenticated :user do
root to: 'users#dashboard', as: "authenticated_root"
end
root 'welcome#index'
end
Error message:
Started GET "/users/sign_in" for 127.0.0.1 at 2015-11-23 23:25:13 +0100
Processing by Devise::SessionsController#new as HTML
Rendered shared/_header.html.erb (2.2ms)
Rendered devise/sessions/new.html.erb within layouts/application (3.1ms)
Completed 500 Internal Server Error in 7ms (ActiveRecord: 0.0ms)
ActionView::Template::Error (No route matches {:action=>"new", :controller=>"guides", :user_id=>nil} missing required keys: [:user_id]):
10: <li><%= link_to "Settings", edit_user_registration_path %></li>
11: <li><%= link_to "My Account", current_user %></li>
12: <% end %>
13: <li><%= link_to "Add tutorial", new_user_guide_path(current_user) %></li>
14: </ul>
15: </nav>
16: </header>
app/views/shared/_header.html.erb:13:in `_app_views_shared__header_html_erb__869860312033883396_70024564174000'
app/views/devise/sessions/new.html.erb:1:in `_app_views_devise_sessions_new_html_erb___1648951009615067685_70024756409300'
And after I changed to current_user.id:
undefined method `id' for nil:NilClass
So basically current user is nil when there is no logged in user - no big suprise. But is there any way to get around this error thanks to some before_filters or before_action and include link to adding guuide that requires logged in user data without user being actually logged in?
You can try this way
`<% if signed_in? %>
<%= link_to "Profile", profile_path %>
<% if can? :update, #user %>
<%= link_to "Admin", admin_root_path %>
<% end %>
<%= link_to "Logout", destroy_user_session_path, method: :delete %>
<% else %>
<%= link_to "Sign in", new_user_session_path %>
<%= link_to "Join Us", new_user_registration_path %>
<% end %>`
And change your
current_user.id to current_user
This worked for me ,hope it will do same for you :-)
Add "Add tutorial" link in else condition:-
<% if user_signed_in? %>
<li><%= link_to "Dashboard", root_path %></li>
<li><%= link_to "Log Out", destroy_user_session_path, method: :delete %></li>
<li><%= link_to "Settings", edit_user_registration_path %></li>
<li><%= link_to "My Account", current_user %></li>
<li><%= link_to "Add tutorial", new_user_guide_path(current_user) %></li>
<% else %>
<li><%= link_to "Log In", new_user_session_path %></li>
<% end %>
Add before_filter in guide controller:-
before_filter :authenticate_user!

Syntax error, unexpected keyword_ensure, expecting keyword_end

I currently have 3 loops im in my _header I have
if current_user.admin? && !current_user?(user)
Also
<% if logged_in? %>
And
<% else %>
It all works fine with no error if i take out
<% if current_user.admin? && !current_user?(user) %>
<li><%= link_to "Admin", users_path %></li>
</end>
When I paste it back in i get the error. I dont know whats wrong with this syntax.
Can anyone help?
<ul class="nav navbar-nav navbar-right">
<% if current_user.admin? && !current_user?(user) %>
<li><%= link_to "Admin", users_path %></li>
</end>
<% if logged_in? %>
<li><%= link_to "Dash", users_path %></li>
<ul class="nav navbar-nav">
<li class="dropdown">
Items<span class="caret"></span>
<ul class="dropdown-menu">
<li><%= link_to "New Item", new_item_path %></li>
<li><%= link_to "Edit Items", user_items_path %></li>
<li>Mass Upload Items</li>
<li>Upload Item Images</li>
</ul>
</li>
</ul>
<ul class="nav navbar-nav">
<li class="dropdown">
Profile<span class="caret"></span>
<ul class="dropdown-menu">
<li><%= link_to "View Profile", user_path(current_user) %></li>
<li><%= link_to "Edit Profile", edit_user_path(current_user) %></li>
</ul>
</li>
</ul>
<li><%= link_to "Messages", users_path %></li>
<li class="dropdown">
Settings<span class="caret"></span>
<ul class="dropdown-menu">
<li>Edit Money Back Policies</li>
<li>Edit Warranty Policies</li>
</ul>
</li>
<li><%= link_to "Log out", logout_path, method: "delete" %></li>
<% else %>
<li><%= link_to "Log In", login_path %></li>
<li>Sign Up</li>
<% end %>
</ul>
</div><!-- /.navbar-collapse -->
</div><!-- /.container-fluid -->
</header>
You're not properly closing the if you pasted :
<% if current_user.admin? && !current_user?(user) %>
<li><%= link_to "Admin", users_path %></li>
</end>
You should try to replace that by :
<% if current_user.admin? && !current_user?(user) %>
<li><%= link_to "Admin", users_path %></li>
<% end %>
structure of if loop in ruby.your end tag of if loop is incorrect.see below
<%if%>
//condition here
<%end%>
can you try this out:
<% if logged_in? && !current_user?(user) && current_user.admin? %>
<li><%= link_to "Admin", users_path %></li>
</end>
Syntex error in closing of if block syntex.
1 <% if current_user.admin? && !current_user?(user) %>
2 <li><%= link_to "Admin", users_path %></li>
3 </end>
Error at line 3, replace line 3 ie </end> with <% end %>

unable to correctly load font-awsome icons in navbar using link_to method in rails

Im trying to add font-awsome icons to my (link_to) links within a simple navbar i created, however im not sure as to how to correctly write the code using ruby syntax as apposed to the html. This is the code I would like to add the icons to:
<nav>
<ul>
<li><%= link_to "Main", root_path %></li>
<li><%= link_to "Employee Profile", profile_path %>
<ul>
<li><%= link_to "Tasks / Activities", "#" %></li>
<li><%= link_to "Vacations", "#" %></li>
</ul>
</li>
<li><%= link_to "Projects", projects_path %></li>
<li><%= link_to "Projects Documents", project_docs_path %></li>
<li><%= link_to "Search", search_path %></li>
<li><%= link_to "Reports", reports_path %></li>
<li><%= link_to "Feedback", feedback_path %></li>
</ul>
I would like each one of my (link_to) tags to have its own font-awsome icon. As an exmample, could you provide me with the correct syntax to include the following icon to my "Employee Profile" section:
<i class="fa fa-user"></i>
Here is a link to the icon's page:
http://fortawesome.github.io/Font-Awesome/icon/user/
Thanks!
Link_to tag can be used as a 'block'. You can use in this way to include font-awesome in link_to
<%= link_to profile_path do %>
<i class="fa fa-user"></i>Employee Profile
<% end %>

Need a simple syntax when using multiple devise user models for the NAV bar, complex conditional

I'm having trouble with coming up with a simple way to write Ruby conditional for this build case. I have 3 devise user models and based on which user logs in I only want the nag bar to show the correct user class. The idea is to have basically 3 blocks of if else statements which uses the devise user_signed_in? helper as you can see below:
<nav class="top-bar">
<section class="top-bar-section">
<ul class="left">
<li><%= link_to "Home", root_path %></li>
<li><%= link_to "Admin Login Page", admin_path %></li>
<li><%= link_to "Company Login Page", company_path %></li>
</ul>
<ul class="right">
<% if user_signed_in? %>
<li><%= link_to "Edit Profile", edit_user_registration_path %></li>
<li><%= link_to "Logout", destroy_user_session_path, method: :delete %></li>
<% else %>
<li><%= link_to "Login", new_user_session_path %></li>
<% if admin_signed_in? %>
<li><%= link_to "Edit Profile", edit_admin_registration_path %></li>
<li><%= link_to "Logout", destroy_admin_session_path, method: :delete %></li>
<% else %>
<li><%= link_to "Login", new_admin_session_path %></li>
<% if company_user_signed_in? %>
<li><%= link_to "Edit Profile", edit_company_user_registration_path %></li>
<li><%= link_to "Logout", destroy_company_user_session_path, method: :delete %></li>
<% else %>
<li><%= link_to "Login", new_company_user_session_path %></li>
<% end %>
</ul>
The problem is that it doesn't really work like this so the question is twofold. First, how to simply this conditional syntax? Second, how to get it to work?
You probably want an elsif here, rather than 3 separate blocks. Try something to the effect of:
if user_signed_in?
...
elsif admin_signed_in?
...
elsif company_user_signed_in?
...
elsif params[:action] == 'index'
...
elsif params[:action] == 'admin'
...
else
...
end
or alternatively:
if user_signed_in?
...
elsif admin_signed_in?
...
elsif company_user_signed_in?
...
elsif params[:action] == 'index'
...
elsif params[:action] == 'admin'
...
elsif params[:action] == 'company_user'
...
else
# handle any other case where none of above conditions are met, e.g. params[:action] == 'foobar'
end
I was able to find a solution for my problem. I will post the solution in the hopes that it will help someone else out later if/when they're looking to solve the same problem. This is for Rails 4 btw.
First, you need to put the following in the applications_controller.rb file.
def after_sign_in_path_for(resource)
case resource
when User then '/'
when Admin then '/admin'
when CompanyUser then '/company'
end
end
Then, refactor the original question views code to this.
<ul class="right">
<% if user_signed_in? %>
<li><%= link_to "Edit Profile", edit_user_registration_path %></li>
<li><%= link_to "Logout", destroy_user_session_path, method: :delete %></li>
<% elsif admin_signed_in? %>
<li><%= link_to "Edit Profile", edit_admin_registration_path %></li>
<li><%= link_to "Logout", destroy_admin_session_path, method: :delete %></li>
<% elsif company_user_signed_in? %>
<li><%= link_to "Edit Profile", edit_company_user_registration_path %></li>
<li><%= link_to "Logout", destroy_company_user_session_path, method: :delete %></li>
<% else %>
<% if params[:action] == 'index' %>
<li><%= link_to "User Login", new_user_session_path %></li>
<% elsif params[:action] == 'admin' %>
<li><%= link_to "Admin Login", new_admin_session_path %></li>
<% else params[:action] == 'company_user' %>
<li><%= link_to "Company Login", new_company_user_session_path %></li>
<% end %>
<% end %>
</ul>
Hope this helps.

Resources