Home > Back-end >  How to fix 'This loop will have at most one iteration' in ruby
How to fix 'This loop will have at most one iteration' in ruby

Time:11-16

I am getting This loop will have at most one iteration for following chunk of code. But when I Add else condition, I get an error.

def self.list_all_rentals_person_id(people, rentals)
  list_all_people(people)
  print 'ID of person: '
  person_id = gets.chomp
  rentals.each do |rental|
    return puts "Rentals:\nDate: #{rental.date}  Book: #{rental.book.title}" if rental.person.id == person_id
    else
      return puts 'No Rental Records Found'
    end
  end

But When I only use if and return, the if condition return. I won't get any error

 def self.list_all_rentals_person_id(people, rentals)
  list_all_people(people)
  print 'ID of person: '
  person_id = gets.chomp
  rentals.each do |rental|
    return puts "Rentals:\nDate: #{rental.date}  Book: #{rental.book.title}" if rental.person.id == person_id
  end
end

CodePudding user response:

An explanation of what you've done wrong has been provided.

However, it seems you really want Enumerable#find.

irb(main):001:0> a = [[4, 5], [2, 9], [7, 6]]
irb(main):002:1* if b = a.find { |x| x[0] > 6 }
irb(main):003:1*   p b
irb(main):004:1* else
irb(main):005:1*   puts "Nothing found"
irb(main):006:0> end
[7, 6]
=> [7, 6]

Translating this to your case:

def self.list_all_rentals_person_id(people, rentals)
  list_all_people(people)
  print 'ID of person: '
  person_id = gets.chomp

  if rental = rentals.find { |rental| rental.person.id == person_id }
    puts "Rentals:\nDate: #{rental.date}  Book: #{rental.book.title}"
  else
    puts 'No Rental Records Found'
  end
end

Or you may want to use Enumerable#select to get all rentals that matching your criteria.

def self.list_all_rentals_person_id(people, rentals)
  list_all_people(people)
  print 'ID of person: '
  person_id = gets.chomp

  matching_rentals = rentals.select { |r| r.person.id == person_id }

  if matching_rentals.empty?
    puts 'No Rental Records Found'
  else
    puts "Rentals:"

    matching_rentals.each do |rental|
      puts "Date: #{rental.date}  Book: #{rental.book.title}"
    end
  end
end

CodePudding user response:

Looking at your code, you have multiple small errors.

At first, Rubocop complains as directly on the first iteration of the loop, as return will end the loop. If you move the return after the loop, it will loop until it finds the first result.

def self.list_all_rentals_person_id(people, rentals)
  list_all_people(people)
  print 'ID of person: '
  person_id = gets.chomp

  rentals.each do |rental|
    return puts "Rentals:\nDate: #{rental.date}  Book: #{rental.book.title}" if rental.person.id == person_id
  end

  puts 'No Rental Records Found'
end

(notice: you can remove return if you want to return the last statement in a function in ruby, as it will always be the return value).

Your other problem is that you can't combine a single line if statement return foo if bar with an else on the second line.

return puts "Rentals:\nDate: #{rental.date}  Book: #{rental.book.title}" if rental.person.id == person_id
else
  return puts 'No Rental Records Found'
end

Should be written as

if rental.person.id == person_id
  return puts "Rentals:\nDate: #{rental.date}  Book: #{rental.book.title}"
else
  return puts 'No Rental Records Found'
end

Though, that will not please Rubocop in this case.

  • Related