Why is the logic not working in my rails app? - ruby-on-rails

In my apps navbar, I have the following code:
apps/views/layout/application.html.erb:
<ul class="nav navbar-nav navbar-right">
<% if user_signed_in? %>
<%if current_user.userinfo(&:info_complete) %>
<li><%= link_to "My profile", userinfo_path(current_user.userinfo.id) %></li>
<% elsif current_user.employer(&:info_complete)%>
<li><%= link_to "My profile", employer_path(current_user.employer.id) %></li>
<%else%>
<li><%= link_to "Complete Profile", application_studoremp_path %></li>
<%end%>
<li><%= link_to "Sign Out", destroy_user_session_path, method: :delete %></li>
<% else %>
<li><%= link_to "Log In", new_user_session_path %></li>
<li><%= link_to "Sign Up", new_user_registration_path %></li>
<% end %>
</ul>
When a user signs up, they will be directed to a page to choose if they want to continue as an employer or student, then they will be directed to a page to fill out userinfo if they choose student, or fill out the employer info if they choose employer. So between signing up and filling out one of the forms, the user will not have "userinfo.id" OR "employer.id". That's why I redirect them to "application_studoremp_path". But the app throws an error saying userinfo.id is not found. Obviously it's not found because it's not created yet, that's why there is an "else" part. Why is the logic not working? :info_complete is a function in both the userinfo model and the employer model checking if the information has been filled out. Everything works fine if the user is already existing (If the userinfo.id or employer.id already exists).
This is the error:
My userinfo.rb model:
class Userinfo < ActiveRecord::Base
belongs_to :user
def info_complete?
name? && email? && college? && gpa? && major?
end

It seems the issue is in your function info_complete that is not returning the right value.
I would suggest you try some test on it, and I guess that when you wanna reference a variable from your model, you should use ":", like this:
def info_complete
:name? && :age?
end

You are using method incorrectly.
The notation method(&:other) is a shorthand for method {|i| i.other}. What is happening here is prefix & is the same as calling to_proc method on object prefixed.
Now, userinfo is a getter, and you can pass it a block (of course) but it will be ignored, it is just a getter.
So all you actually do is check whether userinfo is not nil (or false). You also can tell, because (&:info_complete) does not even fire a NoMethodError (and it should, because there is no info_complete, there is info_complete?).
What you should do is to just use userinfo.info_complete? And if you are concerned user_info could be nil, do it with safe navigation operator: userinfo&.info_complete?
Further reading: Ampersand operator
Safe navigation operator

Related

Ruby on Rails: Conditional Links using presence_in

I have two models, User and Profile, with user_id used as a foreign key to link them. I'd like to put a conditional statement in my footer that looks to see if the current user has a profile. If they do they will see a link to the edit page and, if they don't, to the create/new page.
I tried finding a solution online and I think using the presence_in?(object) method might work but, as a newbie, I don't quite get the syntax.
This is what I have so far if someone can help me get to the finish line :)
<% if current_user.id (something something) %>
<li><%= link_to "Edit Profile", edit_profile_path(:id => current_user) %></li>
<% else %>
<li><%= link_to "New Profile", new_profile_path %></li>
<% end %>
If my question is unclear please let me know and I'll provide a link to my Github page
You can simply do <% if current_user.profile.present? %> to check whether user's profile exists or not. You need have has_one association in User model to get this working e.g has_one :profile

Add param to link_to show method

I have the current code in my traders.index.html file
<ul>
<% #traders.each do |trader| %>
<li><%= link_to trader.name, trader %></li>
<%end%>
</ul>
I want to add an extra parameter to be sent through, I tried
<li><%= link_to trader.name, trader, {:restricted => params[:s]} %></li>
But this doesn't send the parameter, whats the actual format of the link_to to get this done?
You can do:
<%= link_to trader.name, trader_path(trader, restricted: params[:s]) %>

If post exist then display new menu item

I want to be able to display a different menu item if a post exists in a certain page, but unsure of how to best call the controller method in a partial.
I have a career page and if there is a post within that page I would like to display 'NEW' next to the career item in my menu, if no post exist then I just want it to display 'Careers'.
_header located in views -> layouts
<% if Careers.exists?(:id) %>
<li><%= link_to 'Careers NEW', careers_path %></li>
<% else %>
<li><%= link_to 'Careers', careers_path %></li>
<% end %>
try this:
<li><%= link_to "Careers #{(Career.present?)? 'NEW' : ''}", careers_path %></li>

Change "Profile" button in Menu to "User.Name"

So I'm trying to Change in the menu the field "Profile" to the User's name.
<li><%= link_to "Profile", "#" %></li>
So i changed it to
<li><%= link_to User.name, "#" %></li>
but now in the Menu, it states "User", and not the User's Name.
Any Solution?
Thank you
Assuming you get your currently logged in user via current_user method, it should be:
<li><%= link_to current_user.name, '#' %></li>
What you are doing now is sending name message to User class instead of User instance. Since User class doesn't have name method defined, you get this error.

How to show specific link to user that's signed in and on specific page in rails?

I have the following code for part of my navigation:
<% if user_signed_in? %>
<li><%= link_to 'Edit Profile', edit_profile_path(current_user.profile) %></li>
<li><%= link_to 'Edit Account', edit_user_registration_path %></li>
<% elsif user_signed_in? and params[:controller] == 'profiles#edit' %>
<li><%= link_to 'View Profile', profile_path(current_user.profile) %></li>
<li><%= link_to 'Edit Account', edit_user_registration_path %></li>
<% else %>
<li><%= link_to 'Sign up', new_user_registration_path %></li>
<% end %>
I want different links to show depending on where the "user_signed_in" is. However, my <% elsif user_signed_in? and params[:controller] == 'profiles#edit' %> doesn't seem to be working.
What am I doing wrong?
Besides what others already mentioned, as this code is written, when user_signed_in? is true you will always fall into the first block and never hit elsif block.
You would have to fix condition that deals with controller and action AND make this a first condition so that your code will execute as intended.
profiles is your controller, and edit is your action, so you need to specify them as separate things:
elsif user_signed_in? && params[:controller] == 'profiles' && params[:action] == 'edit'
You can use params[:controller], but it only contains the name of the controller. params[:action] will contain the action-name.
Even cleaner is to use controller_name and action_name which are also available.
Like so:
<% elsif user_signed_in? and controller_name == 'profiles' and action_name == 'edit' %>
Tip for the future
You pose this question, but in fact it is extremely easy to show what params[:controller] contains, just do something like
<%= "Controller name = #{params[:controller]}" %>
somewhere in your view. Temporary of course :) But then you would immediately know why your condition does not work.
HTH.
If you want to determine the "url" for showing links or hiding it , you can use :
if request.path == "/profiles/edit"
or the url you'd like . As you can guess , the path's format accepts wildcards too : /profiles/*

Resources