When you create an @variable as opposed to a variable, the @ tells that it is an instance variable.
By opening config > routes.rb, we can use the code resources :articles
to give a lot of different paths to articles (index, create, new, edit, show, update, and destroy).
A nice thing about Ruby on Rails is the program kind of tells you what to work on next. We want to do a new article, so if I type in my browser: 0.0.0.0:3000/articles/new, it will tell me why it can’t do that (no route). So go to route.rb and give it the resources to do it. Reload the page and see that it says uninitialized ArticleController. Guess where we go next? Yup. App > Controllers > new file > “articles_controller.rb”. The code is as follows:class ArticlesController < ApplicationController
def new
end
end
Save it and reload 0.0.0.0:3000/articles/new. Now it is missing the template (view). Go to views and create a new folder called articles. Inside that folder create a file called new.html.erb. Put
<h1>Create a new article</h1>
<%= form_for @article do |f| %>
<% end %>
When you save and run this, you’ll see an error. It says the first argument can’t be empty (because we haven’t made @article yet). So we need to go to articles_controller.rb and create it. So now it should have:class ArticlesController < ApplicationController
def new
@article = Article.new
end
end
Since we got all of that working, we can now build the form on new.html.erb.<h1>Create a new article</h1>
<%= form_for @article do |f| %>
<p>
<%= f.label :title %><br/>
<%= f.text_field :title %>
</p>
<p>
<%= f.label :description %>
<%= f.text_area :description %>
</p>
<p>
<%= f.submit %>
</p>
<% end %>
Everything works, but when you try to click “Create Article” it won’t work. The error says “action create couldn’t be found in ArticlesController”. So we need to define create in ArticlesController. That is done by typing:class ArticlesController < ApplicationController
def new
end
def create
#this will show you what is happening, but just comment it out
#render plain: params[:article].inspect
@article = Article.new(article_params)
if @article.save
flash[:notice] = "Article successfully created
redirect_to articles_path(@article)
else
render 'new'
end
end
private
def article_params
params:require(:article).permit(:title, :description)
end
end
The next thing we need to do is figure out how to deal flash[:notice]
<%= yield %>
<% flash.each do |name, msg| %>
<ul>
<li><%= msg %></li>
</ul>
<% end %>
This all looks good but we don’t have a way of displaying the errors or the validations that occur when you click “Create Article”. We can fix that by entering some code on the new.html.erb page. Right below <% if @article.errors.any? %>
<h2>The following errors prevented the article from getting created:</h2>
<ul>
<% @article.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
<% end %>
Now when I try to create an article with no title, I do get which errors are occurring so that I know why I can’t make an article. But when I put in a correct title and description, I get a message “The action ‘show’ could not be found in ArticlesController.” So I need to define show in ArticlesController found in app > controllers > articles_controller.rb. It doesn’t seem to matter where I place the define, but I’m going to put it right below create.def show
@article = Article.find(params[:id])
end
You now have the <h1>Showing selected articles</h1>
<p>
Title: <%= @article.title %>
</p>
<p>
Description: <%= @article.description %>
</p>
That should be it! We can now create articles by going to 0.0.0.0:3000/articles/new. Make sure to commit and push to git and we are done for now. Next entry will be about editing entries.