Metaphysiker
Metaphysiker

Reputation: 1093

Rails: "Each do"-loop shows an element, which shouldn't be there

I have a problem with an "each do"-loop and I don't know what the cause of it is.

Rails version: Rails 5.2.1 Ruby version: ruby 2.5.1p57 (2018-03-29 revision 63029) [x86_64-linux]

Here is my code:

  <%= @course.sessions.each do |session| %>
    <%= session.topic %><br>
    <hr>
  <% end %>

@course.sessions.count is 0. This course doesn't have any sessions. Yet, there is still something there:

  <%= @course.sessions.each do |session| %> # shows:

[#<Session id: nil, topic: nil, date: nil, description: nil, course_id: 1, created_at: nil, updated_at: nil>] 

When I add a session to the course, the problem remains:

<%= @course.sessions.each do |session| %> # shows:

[#<Session id: 1, topic: "First Session", date: "2018-09-14", description: "First Session", course_id: 1, created_at: "2018-09-14 13:29:30", updated_at: "2018-09-14 13:29:30">, #<Session id: nil, topic: nil, date: nil, description: nil, course_id: 1, created_at: nil, updated_at: nil>] 

The "each do"-loop also occurs twice. See this picture

  @course.sessions.count: <%= @course.sessions.count %><br>
  <%= @course.sessions.each do |session| %>
    <hr>
      Topic: <%= session.topic %><br>
    <hr>
  <% end %>

enter image description here

What seems to be the problem?

EDIT:

Here is my controller:

  def show
    @new_session = @course.sessions.build
  end

EDIT2:

The problem also occurs when using <% .. %>

  @course.sessions.count: <%= @course.sessions.count %><br>
  <% @course.sessions.each do |session| %>
    <hr>
      Topic: <%= session.topic %><br>
    <hr>
  <% end %>

The loop occurs twice, although there is only one session in it.

Upvotes: 0

Views: 76

Answers (2)

arieljuod
arieljuod

Reputation: 15838

On your controller, you do:

@new_session = @course.sessions.build

That instanciates a new empty session object associated to the course and it's iterated when you do @course.sessions.each.

@course.sessions.count does not count that empty object, I guess it's actually doing a count query, so the new session object isn't count since it's not on the database yet.

I guess you can do something like

<% @course.sessions.reload.each do |session| %>

to ignore the recently built session

Upvotes: 1

Igor Drozdov
Igor Drozdov

Reputation: 15045

The problem is that you have a session build for a course here:

def show
  @new_session = @course.sessions.build
end

i.e you put a new session into your @course.sessions collection, that's why you see #<Session id: nil, topic: nil, date: nil, description: nil, course_id: 1 ...>, which is unexpected for you.

The following code will help you to escape this kind of a problem:

def show
  @new_session = Session.new(course: @course)
end

Upvotes: 2

Related Questions