0

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.

Metaphysiker
  • 983
  • 2
  • 18
  • 35
  • are you calling `@course.sessions.build` somewhere? – arieljuod Sep 14 '18 at 13:44
  • @arieljuod yes: (at)new_session = (at)course.sessions.build – Metaphysiker Sep 14 '18 at 13:47
  • 1
    well, that's why you have that empty session, `count` method does a query to the database and counts only persisted records, but `course.sessions.build` instanciates a session associated to the user and is there when you iterate over them – arieljuod Sep 14 '18 at 13:51
  • 2
    You must remove the equal `=` from the statement `<%= @course.sessions.each do |session| %>` (start it with `<% @course.sessions`) – MrYoshiji Sep 14 '18 at 13:52
  • @Metaphysiker I can't, the question was marked as a duplicate from something different than what you asked hahaha (using = there was actually a problem, but not what you where asking, it shouldn't have been marked as a duplicated though) – arieljuod Sep 14 '18 at 14:00
  • @arieljuod The problem occured, even with <% ... %>. I used <%= to show that there is something. – Metaphysiker Sep 14 '18 at 14:01
  • 1
    @arieljuod Ok, I've removed the duplicate tag as this questions has two problems. 1. `<%= @course.sessions.each do |session| %>` should be `<% @course.sessions.each do |session| %>` 2. The problem which you have pointed out. You can post your answer :) – Pavan Sep 14 '18 at 14:08

2 Answers2

2

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
Igor Drozdov
  • 14,690
  • 5
  • 37
  • 53
1

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

arieljuod
  • 15,460
  • 2
  • 25
  • 36