First coined in 1979 by Trygve Reenskaug, an MVC architecture is a design of interactive applications in which every components of the application is broken into three types: models, views, and controllers.
Models are responsible for maintaining the state of the application. Some of this state is transient, lasting for just a couple of interactions with the user. Sometimes the state is permanent and stored outside of the application, often in a database.
In Rails, Models are Ruby classes. Models talk to the database. Models perform business logic, validate, and later store data to the database.
Views are responsible for generating a user interface, normally based on data in the model. Views format the data to be presented to end user.
Rails support multiple format of Views. You can choose to output your data in the form of HTML (complete with the CSS and Javascript), XML, JSON, or even some downloadable formats (like XLS, CSV, or PDF).
Controllers orchestrate the interaction between Views and Models. Controllers receive events from the user, interact with the model, and then call the appropriate view to display the result to the user.
Controllers in Rails are also responsible of parsing requests and handling data submissions, cookies, and sessions.
This is how MVC works in a typical Rails application:
For the time being, we are going to store our app data in a relational database.
In the future, you may step out of this boundary and venture to the land of no relational database such as NoSQL.
But for now, we rely on the relational database that is designed around a set of solid mathematical theory.
Rails provides us with Object-Relational Mapping (ORM) libraries that map database tables to Ruby classes.
For instance, if we have a table called "foods", our Rails app will have a class named "Food".
Rows in "foods" table correspond to objects (instance of) "Food" class. Within these objects, attributes are used to get and set columns in the database.
ActiveRecord is the name of the default ORM provided by Rails. ActiveRecord provides us with class-level methods to perform table-level operations:
food = Food.find(1)
# is the equivalent of query:
# SELECT * FROM foods WHERE id = 1 LIMIT 1;
foods = Food.where(name: "Sirloin Steak")
# is the equivalent of query:
# SELECT * FROM foods WHERE name = 'Sirloin Steak';
# We will learn more about ActiveRecord Query Interface later on
https://www.martinfowler.com/eaaCatalog/activeRecord.html
As mentioned earlier, Rails supports different kind of output formats. The most basic one is HTML wrapped in Embedded Ruby (ERB) format. With ERB files, we can put Ruby codes by putting it between "<%" and "%>" like this:
<h1>Hello from Go-Food!</h1>
<p>
It is now <%= @time %>
</p>
We also have touched this topic earlier in this slide. Here, I just want to add that in addition to coordinating interaction among users, models, and views, controllers are also home to a number of important services like: