Rails comparison not working - ruby-on-rails

In Rails, have a workorders table. Each workorder can have children workorders. I'm trying to create dropdown links to sibling workorders. I'm testing by looking at workorder.id = 30. It has a sibling workorder.id = 20. I don't want to display a link to the same workorder the user is looking at (30).
So I put in a test <% if child.id != #workorder %>. But, the 30 link still displays. I added some logger code to see what's going on.
This is my code:
<li class="dropdown-header">Siblings Links</li>
<% Workorder.find(#workorder).parent.children.each do |child| %>
<%= logger.info 'LOOK HERE ' %>
<%= logger.info child.id %>
<%= logger.info #workorder %>
<% if child.id != #workorder %>
<li><%= link_to child.id_desc, tasks_index4_path(:workorder_id => child) %></li>
<% end %>
<% end %>
The log shows:
LOOK HERE
30
30
LOOK HERE
30
20
Yet the link_to for 30 shows up.
Thanks for the help!

use #workorder.to_i in the comparison

#workorder presumably is a Workorder object. As such, in order to compare the #workorder to the child.id, you'll need to access the id attribute on #workorder in order to make the correct comparison:
<% if child.id != #workorder.id %>

Related

Rails link_to_if not hiding links correctly

For some reason my link_to_if line works, but appears on every show view for my model (Company).
Here's the code:
<% #customers.each do |customer| %>
<li>
<%= link_to_if customer.company_id == #company.id, "#{customer.first_name} #{customer.last_name}", customer_path(customer[:id]) %>
</li>
<% end %>
The issue: I have Customer1 linked to CompanyX. When I go to CompanyZ it shows Customer1, but the link is not a hyperlink. it's just plaintext, and not even supposed to be showing up. However on CompanyX's view, the link works fine. What am I doing wrong here?
If you read the documentation of link_to_if (https://apidock.com/rails/ActionView/Helpers/UrlHelper/link_to_if), it clearly says that [if false] only the name is returned.
In the doc you can find that the (optional) block given is rendered in the false case. So in your case you could pass it an empty block:
<%= link_to_if false, customer_path(customer[:id]) {} %>
In my opinion, if you want to display the link only if one or more customer(s) from #customers are associated to that #company, you should do it this way:
<% #customers.where(company_id: #company.id).each do |customer| %>
<li>
<%= link_to "#{customer.first_name} #{customer.last_name}", customer_path(customer[:id]) %>
</li>
<% %>
if you want to hide some records you can do from from controller to control customers based company
#customers = Company.find(:id).customers
then in your views you can just show it without to compare it
<% #customers.each do |customer| %>
<li>
<%= link_to "#{customer.first_name} #{customer.last_name}", customer_path(customer[:id]) %>
</li>
<% end %>

Rails - If / Else in view returning both branches

I've an 'if / else' running in my view, based on the current URL of the page, and currently the view is displaying what is should were the 'if' both true and false. It's a little tricky to explain, and I've no idea why this is happening - any explanations / solutions will be greatly appreciated!
Before the code, here's a little background:
I have recipes, each of which have one or more cuisines (via has-many-through relationships)
if the URL is, for example, /italian, I want it to display all recipes with the cuisine 'Italian'
otherwise, if the URL is invalid or doesn't have any recipes with matching cuisines, I want it to display a message stating this
(So far, so straightforward right?)
However, when the code runs, it's correctly printing the right recipes (i.e. French meals won't come up on the /italian url), BUT also printing the error message. Here's the code:
In the controller:
#url = request.path.split('/')[2] #returning 'italian', 'french', etc.
And the view:
<% Recipe.all.each do |recipe| %>
<% recipe.cuisines.each do |recipe_cuisine| %>
<% if recipe_cuisine.name.downcase == #url %>
<p><strong><%= recipe.name.humanize %></strong></p>
<ul>
<% recipe.ingredients.each do |recipe_ingredient| %>
<li><%= recipe_ingredient.name %></li>
<% end %>
</ul>
<p><%= recipe.method %></p>
<% else %>
<p>You've reached an invalid page, please return to <#%= link_to 'the homepage', root_url %></p>
<% end %>
<% end %>
<% end %>
To clarify, I've tested the 'recipe_cuisine.name.downcase == #url' line of code, and it's returning true when it should be, false when it shouldn't.
Does anyone know how to resolve this?
Thanks in advance, Steve.
Edit
Here are the routes that affect this:
Rails.application.routes.draw do
get 'recipes/:cuisine' => 'recipes#cuisine'
resources :recipes
end
You defined the following route:
get 'recipes/:cuisine' => 'recipes#cuisine'
This means when you hit /recipes, it uses the cuisine action of the recipes controller (thanks to 'recipes#cuisine').
You also defined an extra :cuisine after the recipes/, which means if you hit /recipes/italian, then you will have a GET param (named cuisine) available in your controller/view.
Here is how you can use it:
# recipes_controller.rb
def cuisine
#recipes = Recipe.all # (use `Recipe.scoped` if using Rails' version < 4)
if params[:cuisine].present?
#recipes = #recipes.includes(:cuisines).where(cuisines: { name: params[:cuisine] })
end
# other stuff
end
# cuisine.html.erb (view)
<% #recipes.each do |recipe| %>
<p><strong><%= recipe.name.humanize %></strong></p>
<ul>
<% recipe.ingredients.each do |recipe_ingredient| %>
<li><%= recipe_ingredient.name %></li>
<% end %>
</ul>
<p><%= recipe.method %></p>
<% end %>
But there is a flaw in this logic: What if I hit /recipes/frenchAndMexicanPlease ? The params[:cusine] will be equal to "frenchAndMexicanPlease", and your DB does not have any cuisine type named like this. In this case, it would display no recipe at all, since the query #recipes.includes(:cuisines).where(cuisines: { name: params[:cuisine] }) would not match any existing record.
I can obviously provide more explanations about the code and logic I used. Hope this helps!
How many cuisines are in the collection? If there are two, and one of them has a name that is equal to #url then you would see the first branch, while any that don't equal #url would show the second branch. You're evaluating that if statement for each cuisine.

Rails - Unique Array in View

Having a Bit of trouble displaying unique results from my database. I have a database called "Activities". Each Activity has an associated Sport through sport_id. There may be many activities with the same sport_id.
I want to display a list of all sports linked to the activities database without displaying (for example "Football") twice.
FYI : Venues have many Facilities and Facilities have many Activities.
Controller:
#sports = Sport.all
#activities = Activity.paginate(page: params[:page])
#facilities = Facility.where(venue_id: #venue.id)
View:
<% #facilities.each do |f| %>
<% #activities.find(:all, :conditions => "facility_id == #{f.id} ").each do |a| %>
<li><%= Sport.find(a.sport_id).name %>, (<%= a.facility_id %>)</li>
<% end %>
<% end %>
This shows:
Football, (2)
Hockey, (2)
Hockey, (2)
Football, (5)
I would like to display just:
Football
Hockey
Any ideas?
A simple solution would be to reduce your array with ruby in the view using: uniq!
<% #facilities.each do |f| %>
<% #activities.find(:all, :conditions => "facility_id == #{f.id} ").uniq! { |a| a.sport_id }.each do |a| %>
<li><%= link_to Sport.find(a.sport_id).name, Sport.find(a.sport_id) %></li>
<% end %>
<% end %>
Another way may be to perform a single query on your DB since Sport what you want to narrow down
In controller:
#sports = Sport.joins(activities: [facility: :venue]).where(facilities: { venue_id: #venue.id }).distinct
In view:
<% #sports.each do |sport| %>
<li><%= link_to sport.name, sport %></li>
<% end %>
I am not sure about your DB schema so I went with what I thought you would have done, but it might needs some tweakings.
I hope I helped you.
try to use reject before each
<% #facilities.reject{your condition here}.each do |f| %>

form_for save input values to session variables

I am trying to create a compare functionality for an index of schools. Currently I am using the following code which takes any checked school and adds it to the school_ids[] in the params.
In my gemfile:
gem 'will_paginate'
In my school's index.html.erb:
<%= form_tag compare_path, :method => 'get' do %>
<%= submit_tag "Compare" %>
<ul>
<% #schools.each do |school| %>
<li>
<%= check_box_tag'school_ids[]', school.id %>
<%= link_to school.name, school %><br>
<%= school.city %>, <%= school.state %>
</li>
<% end %>
</ul>
<% end %>
In my school controller I have:
def compare
#schools = School.find(params[:school_ids])
end
This works great as long as all of the check schools are on the same page. But since I'm using will_paginate to paginate the list of schools, if I change pages, the check boxes do not persist. I'm assuming I need to save to sessions somehow.
Do you mean you want to be able to add a check mark to a school A on page 1 of the index, go to page 2 of the index and add another check mark for school B, then submit the compare form and see schools A and B? If that's the case, then you're correct, you need to get the check boxes into the session. Attach a js click event, like
$('.checkbox_class').click(function(){
$.post('update_session_method', { school_id: $(this).val(), checked: $(this).is(:checked)]);
});
then add a controller method
def update_session_method
session[:school_ids] ||= []
if params[:checked]
session[:school_ids] << params[:school_id]
else
session[:school_ids].delete(params[:school_id])
end
end
then your compare method
def compare
#schools = School.find(params[:school_ids].merge(session[:school_ids] || []))
end

get specific element from ruby block, rails app

When performing a block like:
<% #user.favoured_user.each do |user| %>
<li><%= user.name %></li>
<% end %>
With the favoured_user method returning a limit of 5 users, how would I manipulate the block so that even when there are only 3 users available, I could still return 5 li elements?
I'm guessing a helper would come in to play, and maybe the 'first, second, third, etc.' array methods, but I can't think how to write it.
Any help?
You can try this,
<% 5.times do |i| %>
<li> <%= #user.favoured_user[i].try(:name) %> </li>
<% end %>
You can use in_groups_of
Like:
<% #user.favoured_user.in_groups_of(5).each do |favored_user| %>
<% favored_user.each do |user| %>
<li><%= user.try(:name) %></li>
<% end %>
<% end %>
The first 3 users will come through, and the last two entries will be nil

Resources