Spreadsheet Connection

We will use the API from the google_drive gem to write code that saves
data to the spreadsheet. But where should we put the code?

At first glance, it looks like it could be added to the controller. But
is there somewhere else to put the code?

When you ask such a question, you are putting on the cape of the
software architect. Your decision will be both practical and aesthetic,
aligning (hopefully) with tried-and-true software design patterns, and
impacting the maintainability of the code. More than any other area of
programming, this challenge requires skills honed by experience and
informed by reading and discussion with peers. Given a choice of several
places to insert the new code, the beginner might say, “Does it really
matter?” and make an arbitrary decision. But to the experienced software
engineer, the decision is at the heart of the craft.

Let’s consider our options.

In this case, the form data is received by the controller. It would be a
small extra step to add code to the Contacts controller create method to
connect to Google Drive to save the visitor’s email address and contact
message. The code will work, though seasoned Rails developers will raise
an eyebrow. Why?
Skinny Controller, Fat Model

If you think about it, saving data to Google Drive is a data operation,
and all data manipulation should be handled by a model.

Rails is opinionated, which means there is often a “Rails way” that is
preferred to other approaches. One of the slogans of the “Rails way” is
“skinny controller, fat model.” The slogan exists to remind developers
that separation of concerns makes more modular, maintainable programs.
Data manipulation goes in a model. Controllers should contain only
enough code to instantiate a model and render a web page.

Consequently, we’ll add a method to the Contacts model named
update_spreadsheet that will use the google_drive gem to connect to
Google Drive and save the data. We’ll call the
@contact.update_spreadsheet method from the Contacts controller create
method.