Rails if elsif condition showing wrong section for a split second - ruby-on-rails

I have this condition to show the correct nav bar:
<% if current_user %>
<% if current_user.quality? %>
<%= render 'shared/quality_nav' %>
<% else %>
<%= render 'shared/nav' %>
<% end %>
<% end %>
On my production server everything is fine. On my staging server, I see the quality nav bar for 1 second before the proper nav bar appears - I've never seen this happen before, what could be wrong?
EDIT
how quality is defined:
def quality?
self.role == 'Quality' ? true : false
end
My only possible guess is the staging server is 1gb and no fast enough, but I find that odd. Changing the code to this makes it go away, but I would still like to know why the original code caused that behaviour.
<% if current_user && current_user.quality? %>
<%= render 'shared/quality_nav' %>
<% elsif current_user %>
<%= render 'shared/nav' %>
<% end %>

Related

Display modal (only 1 time) after first login with Ruby on Rails + Devise

I'm trying to show an introduction modal to new user after the first sign in.
<% if user_signed_in? && current_user.sign_in_count == 1 %>
<%= render 'introduction_slides' %>
<% end %>
The sign_in_count works great. but the problem is that user needs to signout and in to stop seeing that modal. Is there any better way to make this happen? Maybe using Cookie?
I figured out with Session 👍
<% if user_signed_in? && current_user.sign_in_count == 1 %>
<% unless session[:introduction_slides] %>
<%= render 'introduction_slides' %>
<% session[:introduction_slides] = true %>
<% end %>
<% end %>

Logic to an if statement

I have the following logic in my view to choose which avatar picture to show depending on whether a persons profile is present
<% if #profile %>
<%= image_tag(#profile.avatar_url(:thumb)) %>
<% else %>
<%= image_tag(default_image_url) %>
<% end %>
Helper method
def default_image_url
hash = Digest::MD5.hexdigest(current_user.email)
"https://secure.gravatar.com/avatar/#{hash}?s=100&d=mm"
end
This works fine when someone has not created a profile, but when they do and still want to use their Gravatar this logic fails as my if condition then needs to be if
<% if #profile.avatar? %>
<%= image_tag(#profile.avatar_url(:thumb)) %>
<% else %>
<%= image_tag(default_image_url) %>
<% end %>
At the moment when a profile is created with no image uploaded by the user, there is no image displayed at all.
How can I cover all scenarios?
Edit
I'm in the process of trying
<% unless #profile || #profile.avatar %>
A bit of refactoring starting from #ArieShaw's answer:
Helper
def profile_image_url
#profile.try(:avatar?) ? #profile.avatar_url(:thumb) : default_image_url
end
View
<%= image_tag profile_image_url %>
You may use Object#try:
<% if #profile.try(:avatar?) %>
<%= image_tag(#profile.avatar_url(:thumb)) %>
<% else %>
<%= image_tag(default_image_url) %>
<% end %>

In Rails 4, how can I change the text in the nav bar based on the current page?

I am working on a Rails 4 project where I would like a different link to appear on the navigation bar depending on the current page. This is how I am trying to set it up:
<ul>
<% if current_page?("/company") %>
<li>Company Space</li>
<% elsif current_page?("/user_page") %>
<li>User Space</li>
<% else %>
<% end %>
</ul>
I know I've written this part correctly, because when I put it in the application.html.erb layout page, it works just fine. When I put the same exact thing in the top nav bar, however, it doesn't work. The nav bar is in a partial called _header.html.erb which is currently rendered in the layout as follows:
<body>
<%= javascript_include_tag "application" %>
<%= render 'layouts/header' %>
<p class="notice"><%= notice %></p>
<p class="alert"><%= alert %></p>
<%= yield %>
<%= render 'layouts/footer' %>
</body>
I assume this has something to do with the nav bar not detecting the current page. I am hoping someone can tell me why this is happening, and ideally I would like to find a relatively DRY solution that would allow me to have this feature. (I have thought of creating separate partials for the different conditions, and then putting the logic for displaying the partial in application.html.erb, but given that this is far from the only content in the nav bar, the maintainability of that seems quite dismal.)
Thanks for any help!
To expand upon nathan's answer, specify action
<% if params[:action] == 'company' %>
<li>Company Space</li>
<% else params[:action] == 'user_page' %>
<li>User Space</li>
<% end %>
This will work... but it doesn't feel like the cleanest way. Perhaps go about doing it with JS for it to be cleaner?
<% if params[:controller] == 'company' %>
<li>Company Space</li>
<% else params[:controller] == 'user_page' %>
<li>User Space</li>
<% end %>
you can make it more cleaner by moving the following to respected helper file.
def nav_bar_content(action)
if action == 'company'
"Company Space"
elsif action == 'user_page'
"User Space"
else
# statement
end
end
and call <li><%= nav_bar_content(params[:action]) %></li> this is on your nav bar

Exit rails gracefully if conditions are met?

I have a code where I would need to exit (php version of die), if certain events occur
Snippet in trace_controller.rb
def show
rule=Rule.new
#order,#order_error=rule.get_order(#order_external_id)
#order_items, #order_items_error=rule.get_order_items(#order)
#order_item_units, #order_item_units_error=rule.get_order_item_units(#order_items)
#outbound_messages, #outbound_messages_error = rule.check_outbound_messages(#order_external_id)
#inbound_messages, #inbound_messages_error = rule.check_inbound_messages(#outbound_message)
......
In show.html.erb
<% unless #order_error.blank? %>
<%= #order_error.html_safe %>
<% else %>
<%= render "trace/display_tabular_data", :data => #order %>
<% end %>
.....
.....
<% unless #order_items_error.blank? %>
<%= #order_items_error.html_safe %>
<% else %>
<% #order_items.each do |order_item| %>
<h5>Order Item</h5>
<%= render "trace/display_tabular_data", :data => order_item %>
<% end %>
<% end %>
......
Most of my functions are dependent on outcome of previous functions. Now take get_order_items function which is dependent on orders. If the order does not exist, there is no need to calculate get_order function as it won't exist either. Additionally, it fires up an error, as it says I am passing it a NIL object when I perform operations on orders inside get_order_item.
Additionally in the show.html.erb - #order_items, and #order_items_error should not even exist if the order does not exist. I just wanna render the function till the order_error, and then stop.
Now, coming from PHP background, I forgot that rails does not have die. So is there an alternate of die? Abort isn't it. I need it to exit disgracefully. Or is my best shot using conditionals if, unless etc...But it will look ugly as the page will become full of them. How would you about it?
To cut off the current action and render the view, you can use return. This will crash with errors if you try to use an unitialized instance variable in the view though.
You can also use render nothing: true which stops the current action and renders nothing.
Perhaps consider redirecting back as well:
flash[:error] = 'There was no order!'
redirect_to :back
I am not sure what exactly you want to do. But this should meet with what you are asking for.
def show
rule=Rule.new
#order,#order_error=rule.get_order(#order_external_id)
unless #order.blank?
#order_items, #order_items_error=rule.get_order_items(#order)
#order_item_units, #order_item_units_error=rule.get_order_item_units(#order_items) unless #order_items.blank?
end
#outbound_messages, #outbound_messages_error = rule.check_outbound_messages(#order_external_id)
#inbound_messages, #inbound_messages_error = rule.check_inbound_messages(#outbound_message) unless #outbound_messages.blank?
end
Similarly, you can add conditions in your view file:
<% unless #order.blank? %>
<% unless #order_error.blank? %>
<%= #order_error.html_safe %>
<% else %>
<%= render "trace/display_tabular_data", :data => #order %>
<% end %>
.....
.....
<% unless #order_items.blank? %>
<% unless #order_items_error.blank? %>
<%= #order_items_error.html_safe %>
<% else %>
<% #order_items.each do |order_item| %>
<h5>Order Item</h5>
<%= render "trace/display_tabular_data", :data => order_item %>
<% end %>
<% end %>
<% end %>
.......
.......
<% end %>
It is just a basic idea what I get from your example, though it was not clear enough to show what you want to achieve. So, whole idea is to check the variable before using it!
One more point I would like to mention, avoid using unless - else, unless should be used alone, if you need to put some logic in else block, why not use if - else. That probably makes more sense than unless - else.

If else not working because it contains end within

I have a a helper that contains a simple on and off switch. I know I have it working because it's working on other pages. However, on this particular page it won't work.. I think its because theres an end within the if else, so it ends the if else early. Here's the code:
I believe this part is working:
<% if popup == "off" %>
<% content_for :main do %>
<% end %>
This part not so much:
<% if popup == "off" %>
<% end %> << this end should be displayed if popup = off
<% end %>
You could do this:
<% if popup == "off" %>
<%= "<% end %>" %> << this end should be displayed if popup = off
<% end %>
or try this:
<% if popup == "off" %>
<% end %> << this end should be displayed if popup = off
<% end %>
If you just want the word end to be displayed, don't enclose it in tags. Anything enclosed in tags is interpreted as Ruby code, anything not is printed exactly as it is.
<% if popup == "off" %>
end << this will now be interpreted as text, not ruby code
<% end %>
ERB (and Ruby) doesn't work like that.
I think you're treating it like you are trying to end an HTML tag instead of an end to a Ruby block, and that you want everything in between those two code segments to run in the content_for block.
Here's what you need. Everything in between will be included in the content_for block:
<% if popup == "off" %>
<% content_for :main do %>
your block code will be evaluated here.
<% end %>
<% end %>
Seems all the suggestions of doing <%= "<% end %>" %> results in a syntax error.. May seem like easy way out by ended up just restructuring my app and got rid of the requirement of <% content_for :main do %>

Resources