简体   繁体   中英

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

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>

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.

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.

Modify your routes file

routes.rb

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM