Let’s generate a controller for our new model. But first… you guessed it! Let’s make a branch for our chapter:
git checkout -b Chapter-10
Right… back to our Controller:
Run the following command from the Contacts
engine (i.e. engines/contacts
)
rails g scaffold_controller Contact --no-helper
First, we need to change the parent of ApplicationController
to the ApplicationController
present in the Core
, as shown in Listing 1:
contacts/app/controllers/blast/contacts/application_controller.rb
module Blast
module Contacts
class ApplicationController < Blast::ApplicationController
end
end
end
We have a few things to change in the controller generated by Rails. First, we need to prefix all the path helpers with blast
. Then, we need to update the contact_params
method to include the parameters we want to keep.
Listing 2 shows the entire controller, including comments about what we changed, so you can just copy/paste it and read it.
contacts/app/controllers/blast/contacts/contacts_controller.rb
require_dependency "blast/contacts/application_controller"
module Blast
module Contacts
class ContactsController < ApplicationController
before_action :set_contact, only: [:show, :edit, :update, :destroy]
def index
@contacts = Contact.all
end
def show
end
def new
@contact = Contact.new
end
def edit
end
def create
@contact = Contact.new(contact_params)
@contact.user = current_user
if @contact.save
# Add blast to access the correct path
redirect_to [blast, @contact],
notice: 'Contact was successfully created.'
else
render :new
end
end
def update
if @contact.update(contact_params)
# Add blast to access the correct path
redirect_to [blast, @contact],
notice: 'Contact was successfully updated.'
else
render :edit
end
end
def destroy
@contact.destroy
# Add blast to access the correct path
redirect_to blast.contacts_url,
notice: 'Contact was successfully destroyed.'
end
private
def set_contact
@contact = Contact.find(params[:id])
end
def contact_params
# Add the parameters we allow
params.require(:contact).permit(:first_name, :last_name, :company,
:email, :phone, :user_id)
end
end
end
end
We prepared some views so you don’t have to think about it. They are basic views with Bootstrap
forms and elements. The only thing that you should remember in those views, is the use of blast.my_path
instead of just my_path
. Copy/paste them appropriately:
contacts/app/views/blast/contacts/contacts/index.html.erb
<%= link_to 'New Contact', blast.new_contact_path,
class: 'float-right btn btn-primary' %>
<h2>Listing Contacts</h2>
<hr>
<div class="panel panel-primary">
<div class="panel-heading">
My Contacts
</div>
<table class="table">
<thead>
<th>ID</th>
<th>First Name</th>
<th>Last Name</th>
<th>Company</th>
<th>Email</th>
<th>Phone</th>
<th></th>
</thead>
<tbody>
<% @contacts.each do |contact| %>
<tr>
<td><%= contact.id %></td>
<td><%= contact.first_name %></td>
<td><%= contact.last_name %></td>
<td><%= contact.company %></td>
<td><%= contact.email %></td>
<td><%= contact.phone %></td>
<td>
<%= link_to 'Show', [blast, contact],
class: 'btn btn-primary' %>
<%= link_to 'Edit', blast.edit_contact_path(contact),
class: 'btn btn-primary' %>
<%= link_to 'Destroy', [blast, contact],
class: 'btn btn-primary' , method: :delete,
data: { confirm: 'Are you sure?' } %>
</td>
</tr>
<% end %>
</tbody>
</table>
</div>
<br>
contacts/app/views/blast/contacts/contacts/_form.html.erb
<div class="row">
<div class="col-md-8">
<% if @contact.errors.any? %>
<div id="error_explanation">
<h2>
<%= pluralize(@contact.errors.count, "error") %>
prohibited this contact from being saved:</h2>
<ul>
<% @contact.errors.full_messages.each do |message| %>
<li><%= message %></li>
<% end %>
</ul>
</div>
<% end %>
<div class="form-group">
<%= f.label :first_name, class: "control-label" %>
<%= f.text_field :first_name, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :last_name, class: "control-label" %>
<%= f.text_field :last_name, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :company, class: "control-label" %>
<%= f.text_field :company, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :email, class: "control-label" %>
<%= f.email_field :email, class: "form-control" %>
</div>
<div class="form-group">
<%= f.label :phone, class: "control-label" %>
<%= f.text_field :phone, class: "form-control" %>
</div>
</div>
</div>
contacts/app/views/blast/contacts/contacts/new.html.erb
<h2>New Contact</h2>
<hr>
<%= form_for([blast, @contact]) do |f| %>
<%= render 'form', f: f %>
<div class="form-group">
<div>
<%= f.submit "Create Contact", class: "btn btn-primary" %>
<%= link_to 'Back', blast.contacts_path, class: 'btn btn-default' %>
</div>
</div>
<% end %>
contacts/app/views/blast/contacts/contacts/show.html.erb
<h2><%= @contact.first_name %></h2>
<hr>
<div class="row">
<div class="col-md-8">
<strong>First Name:</strong>
<%= @contact.first_name %>
<br/>
<strong>Last Name:</strong>
<%= @contact.last_name %>
<br/>
<strong>Company:</strong>
<%= @contact.company %>
<br/>
<strong>Email:</strong>
<%= @contact.email %>
<br/>
<strong>Phone:</strong>
<%= @contact.phone %>
</div>
</div>
<hr>
<%= link_to 'Edit', blast.edit_contact_path(@contact), class: "btn btn-primary" %>
<%= link_to 'Back', blast.contacts_path, class: 'btn btn-default' %>
contacts/app/views/blast/contacts/contacts/edit.html.erb
<h2>Editing Contact</h2>
<hr>
<%= form_for([blast, @contact]) do |f| %>
<%= render 'form', f: f %>
<div class="form-group">
<div>
<%= f.submit "Update Contact", class: "btn btn-primary" %>
<%= link_to 'Back', blast.contacts_path, class: 'btn btn-default' %>
</div>
</div>
<% end %>
That’s it for the views!
If we want to access the contacts somehow, we need to define some routes for it. Let’s add them as you can see in Listing 8:
contacts/config/routes.rb
Blast::Core::Engine.routes.draw do
scope module: 'contacts' do
resources :contacts
end
end
Note that we are just extending the Core
routes. This means that in any of our Blast
engines, all the routes are easily accessible by using blast.my_path
.
Let’s see what it looks like in the browser. Access http://localhost:3000/contacts
and you should see Figure 1:
Ow, not that great, huh? Why don’t we see the beautiful layout that we created in the Core
? Because we have a layout in Contacts
that overrides the Core
version.
Simply delete the layouts folder in the Contacts
engine or run the following command from the Contacts
folder.
rm -r app/views/layouts
Restart your server and refresh your page, and you should see Figure 2:
Nice! But hey, having to type the url is annoying… we want a link in our menu!
We’ll fix that in the next chapter.
Once again,
git status
git add .
git commit -m "Added the Contact Controller and Views"
git push origin Chapter-10
In this chapter we added our Contacts Controller and its related views.
blast.my_path
by extending the Core
routes.
In the next chapter we will learn how to extend the Core
views and add a “Contacts” link in the Navigation bar.