NoMethodError undefined method ` ' for nil:NilClass - ruby-on-rails

I'm novice with rails and starting with http://guides.rubyonrails.org/getting_started.html stucked in 5.7 Showing Articles with following error:
NoMethodError in Articles#show
Showing /home/jakub/workspace/blog/blog/app/views/articles/show.erb where line #3 raised:
undefined method `title' for nil:NilClass
Where the source is :
<p>
<strong>Title:</strong>
<%= #article.title %>
</p>
<p>
and articles_controller.rb is:
class ArticlesController < ApplicationController
def index
#articles = Article.all
end
def create
#article = Article.new(article_params)
#article.save
redirect_to #article
end
private
def article_params
params.require(:article).permit(:title, :text)
end
def show
#article = Article.find(params[:id])
end
end
and rake routes command brings:
Prefix Verb URI Pattern Controller#Action
welcome_contact GET /welcome/contact(.:format) welcome#contact
welcome_index GET /welcome/index(.:format) welcome#index
articles GET /articles(.:format) articles#index
POST /articles(.:format) articles#create
new_article GET /articles/new(.:format) articles#new
edit_article GET /articles/:id/edit(.:format) articles#edit
article GET /articles/:id(.:format) articles#show
PATCH /articles/:id(.:format) articles#update
PUT /articles/:id(.:format) articles#update
DELETE /articles/:id(.:format) articles#destroy
root GET / welcome#index
Any idea what might cause this issue?
Where should I look for ?

Your show action is private, therefore the instance variable #post cannot be used in the view. Move it to a public scope and the problem should be fixed.

Move your show action to public block.
undefined method `***' for nil:NilClass is actually shown when you are trying to access a object property which is actually not created yet.
Always check on view like this:
#atrile.title if #article.title.present?

Related

undefined method `comments_path' which I can't find in the code files

I am getting the error below (NoMethodError) while trying to add a new comment to an article , the problem is that it refers to undefined method `comments_path' which I can't find in the code files
Please help
Note:
I have tried to search about this error , but results I found were not relevant also the problem is the error is pointing to something I can't find.
The error is shown below:
NoMethodError in Comments#new
Showing /home/abc/my_ruby_projects/myblog3/app/views/comments/_form.html.erb where line #1 raised:
undefined method `comments_path' for #<#:0x007fb57888bf28>
Did you mean? font_path
Extracted source (around line #1):
<%= form_with model: #comment do |form| %>
<% if comment.errors.any? %>
<div id="error_explanation">
<....>
<ul>
Trace of template inclusion: app/views/comments/new.html.erb
Rails.root: /home/abc/.../myblog3
I have defined nested routes for articles & comments as shown below:
resources :articles do
resources :comments
end
my routes seems correct , as shown below:
Prefix Verb URI Pattern Controller#Action
rails_admin /admin RailsAdmin::Engine
article_comments GET /articles/:article_id/comments(.:format) comments#index
POST /articles/:article_id/comments(.:format) comments#create
new_article_comment GET /articles/:article_id/comments/new(.:format) comments#new
edit_article_comment GET /articles/:article_id/comments/:id/edit(.:format) comments#edit
article_comment GET /articles/:article_id/comments/:id(.:format) comments#show
PATCH /articles/:article_id/comments/:id(.:format) comments#update
PUT /articles/:article_id/comments/:id(.:format) comments#update
DELETE /articles/:article_id/comments/:id(.:format) comments#destroy
articles GET /articles(.:format) articles#index
POST /articles(.:format) articles#create
new_article GET /articles/new(.:format) articles#new
edit_article GET /articles/:id/edit(.:format) articles#edit
article GET /articles/:id(.:format) articles#show
PATCH /articles/:id(.:format) articles#update
PUT /articles/:id(.:format) articles#update
DELETE /articles/:id(.:format) articles#destroy
Your form is looking for a route to which it can post the comment updates.
Your routes config likely needs something like
resources :comments
A command line call to list routes will now show you this comments_path it's looking for
rake routes
And then you'll need a CommentsController with an update method/action to handle the postback.
class CommentsController
def edit
end
def update
# save data
end
end
If you're trying to add comments to an article I imagine you have a nested resource where an Article has many comments. Now your /config/routes.rb would have an entry like:
resources :articles do
resources :comments
end
and assuming there is accept_nested_attributes in your /models.article.rb model.
Now in your view usually your form should look something similar to:
<%= form_for [#article, #comment] do |f| %>
When routing I find it useful using the rails routes command, but once they grow too much instead of piping the output to grep I'd rather use the gem sextant in development.

rails generates wrong 'show' route

i have following show function:
def show
#article = Article.find(params[:id])
end
my routes.rb looks like this:
resource :articles
but when i run rake routes, i get this output:
articles POST /articles(.:format) articles#create
new_articles GET /articles/new(.:format) articles#new
edit_articles GET /articles/edit(.:format) articles#edit
GET /articles(.:format) articles#show
PATCH /articles(.:format) articles#update
PUT /articles(.:format) articles#update
DELETE /articles(.:format) articles#destroy
root GET /
as you can see the articles#show route is wrong because an :id is needed to show a single article.
resource :articles
should be
resources :articles
But you have discovered what resource method does :)

what is the difference between redirect_to #article and article_path

I am following this rails guides. And I have this following code
class ArticlesController < ApplicationController
def new
end
def show
#article = Article.find(params[:id])
end
def create
#article = Article.new(article_params)
#article.save
redirect_to #article
end
private
def article_params
params.require(:article).permit(:title, :text)
end
end
In the above code, in the create action, I have modified #article to article_path. Which I believe is the same as per the routes.
Prefix Verb URI Pattern Controller#Action
welcome_index GET /welcome/index(.:format) welcome#index
root GET / welcome#index
articles GET /articles(.:format) articles#index
POST /articles(.:format) articles#create
new_article GET /articles/new(.:format) articles#new
edit_article GET /articles/:id/edit(.:format) articles#edit
article GET /articles/:id(.:format) articles#show
# the above route
PATCH /articles/:id(.:format) articles#update
PUT /articles/:id(.:format) articles#update
DELETE /articles/:id(.:format) articles#destroy
So as per the routes, I mentioned the article_path. But when I did that, it redirects me to /articles instead of /articles/:id
can anyone explain me what is happening.
This seems pretty obvious to me.
When you redirect to #article you are redirecting to THAT article defined by that instance stored in the variable. This surely means /articles/:id, where :id is the id of THAT article stored in the variable.
But when you redirect to articles_path you're not going to a particular article, but to the URL of all articles, i.e., /articles. If you redirect to article_path (now singular) without telling which article do you want, you are going to be redirected the same, to a point where you may find all articles, i.e., /articles
It is just a question of thinking about the semantics of the REST calls.
Hope it helps!
article_path will need to be called with a param of either article.id or #article (an object that responds to to_param)
For a correct redirect you have to use redirect_to article_path(#article). This way Rails knows to what article it should redirect to.

undefined local variable or method `welcome_goodbye_path' in Rails?

I am a beginner in rails and trying to learn using "Agile Web Development using Rails".I wanted to create a link to a webpage.This is my code:
<h1>Hello, Rails!</h1>
<p>
It is now <%= Time.now %>
</p>
<p>
Time to say
<%= link_to "Goodbye", welcome_goodbye_path %>!
</p>
But this gives error...
undefined local variable or method `welcome_goodbye_path'
What am I doing wrong ?
This is the code of my welcome controller:
class WelcomeController < ApplicationController
def index
end
def goodbye
end
end
This is the result of rake routes:
Prefix Verb URI Pattern Controller#Action
articles GET /articles(.:format) articles#index
POST /articles(.:format) articles#create
new_article GET /articles/new(.:format) articles#new
edit_article GET /articles/:id/edit(.:format) articles#edit
article GET /articles/:id(.:format) articles#show
PATCH /articles/:id(.:format) articles#update
PUT /articles/:id(.:format) articles#update
DELETE /articles/:id(.:format) articles#destroy
welcome_index GET /welcome(.:format) welcome#index
POST /welcome(.:format) welcome#create
new_welcome GET /welcome/new(.:format) welcome#new
edit_welcome GET /welcome/:id/edit(.:format) welcome#edit
welcome GET /welcome/:id(.:format) welcome#show
PATCH /welcome/:id(.:format) welcome#update
PUT /welcome/:id(.:format) welcome#update
DELETE /welcome/:id(.:format) welcome#destroy
root GET /
You'd have to show config/routes.rb. You need something in there like:
get 'goodbye', to: 'welcome#goodbye', as: 'welcome_goodbye'

How is params[:id] available to the create action in Rails?

I'm learning Rails and am practicing by writing the classic blog application.
def update
#article = Article.find(params[:id])
#article.update(article_params)
flash.notice = "Article '#{#article.title}' updated!"
redirect_to article_path(#article)
end
How is params[:id] available to the update method? My form_for just passes in the #article object from:
def edit
#article = Article.find(params[:id])
end
From looking at http://guides.rubyonrails.org/form_helpers.html#binding-a-form-to-an-object, the url that the form will POST to is /articles/create. It doesn't seem to have a query string, so id doesn't seem to be sent via GET. And from what I understand, params[:articles] is all that is being passed in via POST. So how is params[:id] available to the update action?
update is a PUT, and the url constructed is /articles/1
create is a POST, and the url constructed is /articles
This is what really is in the doc.
So now you can see where the id param comes from in update, and yes there is no id for create :)
It's go to update through rails router. Read this. If you look into config/routes.rb of your application you will find something like this:
resources :articles
and if you run rake routes task inside you application it'll return something like:
articles GET /articles(.:format) articles#index
POST /articles(.:format) articles#create
new_article GET /articles/new(.:format) articles#new
edit_article GET /articles/:id/edit(.:format) articles#edit
article GET /articles/:id(.:format) articles#show
PATCH /articles/:id(.:format) articles#update
PUT /articles/:id(.:format) articles#update
DELETE /articles/:id(.:format) articles#destroy
so it's how RESTful resource are maps HTTP verbs. So when you create article there is no :id because obviously you will get it from DB auto increment counter. And when you update it, you already have id and route your request to /articles/:id with HTTP PUT request. And :id there is query param that will be available in controller action.
#article = Article.find(params[:id])
is returning instance of article include the ID of the article and all the fields that are in the database.
then (i guess you have form) in parsing the instance and show all the fields in the model.
then when you press submit it pass all changes in hash into update method(PUT method in browser).
hope in answered your question.

Resources