Rails undefined method `each' for nil:NilClass...but it is defined

685 Views Asked by At

I have searched for hours, tried every possible fix. I cannot make this work. The error is:

  *NoMethodError in Articles#index
  Showing /Users/myname/blog/app/views/articles/showall.html.erb where     line #21 raised:
undefined method `each' for nil:NilClass*

showall.html.erb is a view. It is rendered from the 'article' controller. (both posted below). There is a route to showall, and it works fine. Currently the route is configured as:

get 'article/showall'

But, I have also tried it as:

resources :articles do
  get 'showall'
resources :comments

Both routes worked, but neither had an effect on the issue.

There is a method in the controller, its not private:

def showall
   @articles = Article.all
end

The offending piece of code in the view is:

 <% @articles.each do |article| %>
 <tr>
  <td><%= article.title.truncate(30) %></td>
  <td><%= article.author %></td>
  <td><%= article.manufacturer %></td>
  <td><%= article.model %></td>
  <td><%= article.displacement %></td>`

<% end %>

I actually cut and pasted, the piece of code from the index.html.erb view, where it works perfectly. I have tried every nuance of pluralization I can think of. Any help would be greatly appreciated.

This applicable parts of the controller:

class ArticlesController < ApplicationController
 skip_before_action :authorize, only: [:index, :show, :showall]

 #Filter used to catch nonlogged in users 
 before_filter :require_user, :only => [:index]

#method that checks if logged in, sends them to showall if not.
def require_user
unless User.find_by(id: session[:user_id])
  render 'showall', :notice => "Please log in to read articles."
end
end

def index

@articles = current_user.articles

end

#should list articles, but throws undefined method 'each' error
def showall
@articles = Article.all
end

Here is the entire view:

 <%= render "menu" %>

 <body>
 <font color="yellow"><%= flash[:notice] %></font>
 <br>
 <font color="grey">Motorcycle Articles</font>
 <%= link_to 'Post New Article', new_article_path %> 
 <br>

 <table>
 <tr>
 <th>Title</th>

 <th>Author</th>
 <th>Brand</th>
 <th>Model</th>
 <th>Displacment</th>
 <th>Last Edited On:</th>
 <th>Article</th>
 </tr>
 <% @articles.each do |article| %>
  <tr>
  <td><%= article.title.truncate(30) %></td>
  <td><%= article.author %></td>
  <td><%= article.manufacturer %></td>
  <td><%= article.model %></td>
  <td><%= article.displacement %></td>

  <% end %>
  </table>
  <br>
   All articles are property of their respective owners.

 </body>
3

There are 3 best solutions below

5
On BEST ANSWER

You are calling render 'showall', which renders the view. This is different than 'redirect_to', which calls the controller action. Since you are setting the value of @articles with a nil value (current_user is not set), you get this error.

To clarify, you need to either redirect_to the 'showall' action or redefine @articles to equal Article.all before rendering the view. Personally I'd redirect.

0
On

Route is triggering index action, see:

NoMethodError in Articles#index

You get the error because current_user.articles is nil.

You need to make sure Articles#showall is appearing in the log, that will mean that showall method is called.

Do that creating routes:

get '/articles', to: 'Articles#showall'
resources :articles

This is not recommended. There are several parts to improve. But it should make the error disappear.

1
On

Modify your routes file

routes.rb

resources :articles do
  collection do
    get 'showall'
  end
end