Rails undefined method `each' for nil:NilClass...but it is defined - ruby-on-rails

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

Related

Rails error-undefined method `id' for nil:NilClass

I'm trying to get the data from the phrases_term model to the view, but I'm getting an error.
Phrases_term model:
Phrases_term(id, term_id, phrase_id)
phrases_terms_controller.rb
class PhrasesTermsController < ApplicationController
before_action :authenticate_user!
before_action :set_term
def new
#phrases_term = PhrasesTerm.new
end
def create
#phrases_term = #term.phrases_terms.new(phrases_term_params)
if #phrases_term.save
redirect_to term_phrases_term_path(#term, #phrases_term), notice: "Phrases_Term was successfully created"
else
render "new"
end
end
private
def phrases_term_params
params.require(:phrases_term).permit(:term_id, :phrase_id)
end
def set_term
#term = Term.find(params[:term_id])
end
end
Phrases_term show view, show.html.erb:
<div class="container">
<table class="table">
<thead>
<tr>
<th>ID</th>
<th>Phrases_ID</th>
<th>Term_ID</th>
</tr>
</thead>
<tbody>
<tr>
<td><%= #phrases_term.id %></td>
<td><%= #phrases_term.term_id %></td>
<td><%= #phrases_term.phrase_id %></td>
</table>
<%= link_to 'Back', terms_path %> |
<%= link_to 'Edit', edit_term_path %>
</div>
The error I'm getting:
Error: Eundefined method `id' for nil:NilClass
You're getting an undefined method 'id' for nil:NilClass error because your show.html.erb view doesn't know what #phrases_term is. Hence calling the id method on a variable that doesn't exist yet throws an error. You need to define the variable you're using in the right controller under the right action. So adding:
def show
#phrases_term = PhrasesTerm.find(params[:id])
end
in you phrases_terms_controller.rb should solve the error.

creating a button to update a database entry in ruby

I have created a database of ideas with a votes field. I want users to be able to press a button to increase the vote count of an idea and then refresh the screen. I have created a method called increment_vote, but cannot seem to find how to save the new vote value in my database. This is my part of my index.html.erb code:
<% #ideas.each do |idea| %>
<tr>
<td><%= idea.content %></td>
<td><%= increment_vote(idea) %></td>
<td><%= link_to 'Vote', ideas_path(:mode => "Vote"), :class => "button", :method => :get %></td>
</tr>
If I call the increment vote method from the link to vote code, I get an "undefined method `to_model' for true:TrueClass. Did you mean to_yaml" error.
This is my method code in the ideas.controller:
helper_method :increment_vote
def increment_vote(idea)
idea.votes +=1
idea.save
end
This is currently causing the error, but it is increasing the vote of the first idea in the table.
Can anyone please help?
You can't call increment_vote method from view, you need to create controller action for it and call it when the user clicks the link
# views/ideas/index.html.erb
<% #ideas.each do |idea| %>
<tr>
<td><%= idea.content %></td>
<td><%= link_to 'Vote', upvote_idea_path(idea), class: "button", method: :post %></td>
</tr>
<% end %>
# routes.rb
resources :ideas do
post :upvote, on: :member
end
# ideas_controller.rb
def upvote
Idea.find(params[:id]).upvote
redirect_to :index
end
# models/idea.rb
def upvote
update(votes: votes + 1)
end

Editing multiple records in one form - Rails

I'm trying to edit multiple records using one form, so the user can edit a few records then press submit at the end rather than after each individual one. I've posted my current code, and I get this error:
undefined method `connection_connection_path'
Controller
def show
#customer = Customer.find(params[:id])
#connection = #customer.connections
respond_to do |format|
format.html # show.html.erb
format.json { render json: #customer }
end
end
View
<table class="table">
<thead>
<th>Interface</th>
<th>Device</th>
<th>Speed</th>
<th>Site</th>
<th>Capable</th>
<th>Notes</th>
</thead>
<%= form_for(#connection) do |f| %>
<% #connection.each do |l| %>
<tr>
<td><%= l.interface %></td>
<td><%= l.device %></td>
<td><%= l.speed %></td>
<td><%= l.site.name%> </td>
<td><%= f.check_box :check %></td>
<td><%= f.text_field :notes %></td>
</tr>
<% end %>
<tr><%= f.submit %></tr>
</table>
<% end %>
routes
resources :connections
resources :sites
resources :customer_sites
resources :customers
root :to => "customers#index"
so where is your submit button?? and it should not done in show, maybe you might create a new method in your controller and do the multiple edit function.
The basic concept is when you have checks, you need to pass an array of your object to your method, and update them one by one. or you can do that using JS as well.
refer this railscast
http://railscasts.com/episodes/165-edit-multiple
and this stackoverflow
Rails 3 Edit Multiple Records in a Single Form
these resources you can get easily by google :D
if still have problem, just come and ask here again

Couldn't find tasksadmins with id=15

I have two controllers: Tasksadmins and Workers.
I defined a table, is called: Tasksadmin, and has the parameters: admin_email, worker_email, task, done. the done option is check box.
in Tasksadmins controller, I defined:
def edit
#tasksadmin = Tasksadmin.find(params[:id])
end
in this controller, I can edit all the row of the table. it works fine!
in the Workerscontroller, I tried to define:
def edit
#tasksadmin = Tasksadmin.find(params[:id])
end
I did it because I want to get all of the parameters of the row, but I will let the worker an option to change only the parameter of done.
unfortunately, I got this error:
ActiveRecord::RecordNotFound in WorkersController#edit
Couldn't find Worker with id=15
I think I got it because the url is: localhost:3000/workers/15/edit
(pay attention to: workers/15/edit)
in order to understand where the problem is, I wrote the next word in my models/workers/edit.html.erb:
hello!
so I think the problem is with the work workers in the url :/
how can I fix it please?
UPDATE:
this is the index of the workerscontroller:
def index
#tasks_worker = Tasksadmin.where(:worker_mail => current_user.email)
respond_to do |format|
format.html # index.html.erb
format.json { render json: #workers }
end
end
this is index.html.erb:
<h1>Listing workers</h1>
<table>
<tr>
<th>Admin_mail</th>
<th>Task</th>
<th>Done</th>
<th></th>
<th></th>
<th></th>
</tr>
<% #tasks_worker.each do |task| %>
<tr>
<td><%= task.admin_mail %></td>
<td><%= task.task %></td>
<td><%= task.done %></td>
<td><%= link_to 'Edit', edit_worker_path(task) %></td>
</tr>
<% end %>
</table>
It seems like Worker with ID=15 doesn't exist.
Worker.find(params[:id])
Will raise ActiveRecord::RecordNotFound if that Worker doesn't exist.
You can go into the rails console and try:
Worker.find(15)
If you want to have find return nil instead of raising you can use:
Worker.find_by_id(params[:id])
I'm not too sure about this (maybe somebody can correct me), but I think
#tasksadmin = Tasksadmin.find(params[:id])
just defines the variable #tasksadmin.
Now, if you call the localhost:3000/workers/15/edit-URL, Rails is actually searching for a worker with ID 15 (Worker.find(15))
What do you want to accomplish?
I added this line in Workerscontroller:
load_and_authorize_resource :except => [:edit, :update]
and this line in Tasksadminscontroller:
load_and_authorize_resource :except => [:update, :show]

Rails: Correct Way of Using the method of PostController in the Index file

I'd like to learn how to use the methods defined in the controller in the index page.
I'm trying to implement "like" button on my blog.
PostController
def like
#post = Post.find(params[:id])
#post.like += 1
#post.save
end
In the index where all the posts are listed, I tried something like this.
<% #posts.each do |post| %>
<tr>
<td><%= post.name %></td>
<td><%= post.created_at.strftime("%Y/%m/%d, %I:%M%p") %></td>
<td><%= post.view %></td>
<td><%= link_to 'like', like_post_path %></td>
<td>hate</td>
</tr>
<% end %>
I got the idea by looking at the code,
<%= link_to 'make a new post', new_post_path %>
<%= link_to 'Edit', edit_post_path(post) %>
I thought the way to use methods in the controller in the index page was
(method in PostController)_post_path, but it seems I got it wrong.
undefined local variable or method `like_post_path'
I've also tried like(post).
My ultimate goal is to make this function as an ajax function, so I expected it to be a form like
<% link_to_function 'like', like_post, remote: true %>
What's the right way of using the method "like" in this case?
You'd need to define a named route to make this work. Like:
# in config/routes.rb
resources :posts do
member do
get 'like'
end
# OR
get 'like', :on => :member
end
# in `rake routes` this would show up as:
like_post GET /posts/:id/like(.:format) posts#like
# you'd reference in a view like:
like_post_path(#post)

Resources