Monday morning — back to my coding den in the basement of the Cobble Hill Starbucks! It must be a sign that I’m onto something when I spend much of the weekend wishing I were back here, rather than out socializing. Today, I’m spending some time reviewing the architecture of Rails apps, namely the MVC design pattern, and playing around with my simple demo app.
I first was introduced to MVC (Model-View-Controller) architecture several months ago in my Product Management class. The gist, of course, is this: separate your code into groupings based on the function they perform vis-a-vis the browser and the database. Controllers receive user input from the browser and interact with Models, which are linked to the Database. After receiving data from the Database via the Models, the Controller invokes the appropriate View, usually generating ERB (embedded Ruby) HTML templates and rendering them in the browser. (N.B. This is a helpful way to think about how MVC interacts with a database: The controller tells the database what to do, and the model know how to do it.) A well-structured Rails app does not deviate from this convention; code governing display is only found in the Views, code interacting with the database only exists in Models, and code linking these two belongs in the Controllers. Sticking to this design pattern will make your code modular and much easier to maintain as you inevitably make changes in the future. When Rails creates “scaffolding,” it means that it is creating an MVC skeleton, to which you must then add the logic.
Rails functions slightly differently than a regular MVC framework in a couple ways: (1) Incoming requests are sent first to a Router, which determines where in the application that request should be sent, and ultimately activates an “action” somewhere in the controller code; (2) Rails relies on Active Record as the pre-configured ORM (Object-Relational Mapping) level, which maps the applications objects onto a relational database like SQL; (3) Views and Controllers in Rails are bundled together into one component called the Action Pack. This doesn’t mean they are jumbled together; Rails provides the separation necessary to demarcate between control and presentation logic.
MODELS: libraries map database tables to classes. Each table in our database requires an analogous class in our program. Each row in that table represents an instance/object of that Class, and each column represents an attribute of that object. Class methods perform table-level operations, and instance methods perform operations on the individual rows.
CONTROLLERS: Because so much of the interaction between user and database is taken care of automatically by Rails, the Controllers are actually quite simple and easy to develop/maintain. Controllers are also responsible for the following services: (1) routing external requests to internal actions; (2) managing caching; (3) managing helper modules, which extend the capabilities of the view templates without bulking up their code; (4) managing sessions, giving the users the impression of ongoing interaction with our applications.
Installing Rails / First Demo App!
After several weeks of learning the basics of Ruby, I feel like I’m finally ready to ride some Rails. I actually installed Rails a while back while I was going through the official Rails Tutorial, but I had less than a clue as to what I was doing then. So I’m forcing myself to go through the steps again and try to understand all the pieces in play.
- Ruby Interpreter - also known as the Ruby MRI or CRuby, this is the software that interprets Ruby code. When you “download Ruby,” this is what you’re downloading.
- RubyGems - the package manager that allows you to download gems (modular bits of pre-written code/programs that you can add to your own software, saving you time and effort. From the RubyGems site: “Ruby developers create and publish awesome gems which address specific requirements, solve specific problems or add specific functionality. Anyone who comes across similar requirements or problems can use them and eventually improve them.”)
- Ruby on Rails - a framework for quick and easy software development, relying heavily on convention over configuration. Imposes an MVC structure on your code, and allows for the creation of scaffolds upon which you build your business logic.
- Database - The place where data is stored. Could be relational database (SQL) or non-relational (NoSQL), like MongoDB.
- Production Web Server - Don’t understand all of the parts to this yet, but this is what deploys and hosts your program so that others can access it. Heroku is one option, I believe. I think this is where the term LAMP stack comes into play as well…
- Xcode - Apple’s suite of developer tools (IDE - integrated development environment). Not sure why I need this yet, or what it does.
- Version Control - namely Git, which allows you to store and keep track of any changes to your code as well as collaborate with others via GitHub.
And voila: Rails is installed, and I’m ready to build my first application!
After a couple of minutes playing around with my first demo app, I’m realizing how easy Rails makes life. By generating a new controller, Rails automatically creates that controller, any views that you indicate as parameters, routes from the controller to those views, assets including coffeescript and scss, and tests and helpers for this controller. (Granted, I don’t know what tests and helpers do yet, but I’m sure they’re important!) All of this is done just by typing in “rails generate controller Say hello goodbye” at the command line, where “Say” is the controller and “hello” and “goodbye” are, I think, different methods for the SayController class.
Okay, I just figured out a little of what helpers do: helpers allow you to use the link_to() method, which lets you link your pages together based on paths defined within your app, rather than absolute or relative paths that may change as you develop you app. The link_to() method takes two parameters: the first is the text that will be displayed and linked, and the second is the path that you want to link to. It looks something like this: <%= link_to “Hello”, say_hello_path %>.
Well that’s it for today. Tomorrow I’ll be exploring more of the Architecture of Rails Apps, and coming to grips with the MVC structure. That is if I don’t spend all day eating soup dumplings and singing karaoke with Fisher…
I love Christmas….Christmas is good for criminals. -John Waters
The Elements of Ruby
I just made it through my first programming book “Learn to Program” by Chris Pine. Woohoo! Before jumping into my next book on Agile Web Development with Rails, I decided to do a quick review of the major concepts that were covered in the book:
- Classes: Classes are basically a grouping of objects that behave the same way. Everything in Ruby is an object, and every object is an instance of some class. A bunch of classes come pre-programmed into Ruby (primitives, see below), but you can also create your own classes. Examples of pre-built classes are String, Integer, Fixnum, Float, Array, Hash, Range, Proc, Time, Dir, File, and Class.
- Variables: A variable is a way to temporarily store information. There are a couple different types of variables that all differ in their variable scope: local variables, which only are accessible inside the code construct in which they are declared (for loop, etc); instance variables (@), which are limited to a single instance of an object; class variables (@@), which are shared amongst all instances of a class; and global variables ($), which are accesible anywhere within the program and are, evidently, frowned upon because of their potential for bugs.
- Methods: The “verbs” of Ruby, in contrast to the object “nouns”. Methods are like variables in that they store information, but they store functions/actions rather than values, and these functions can be called at any point to manipulate objects. Methods are “called on” objects but they also have objects (integers, strings, variables, procs, etc) “passed into” them as “parameters,” kind of like the x in an f(x) function from algebra. New methods are created like so: def method_name parameter1, parameter2 OR def method_name(parameter1, parameter2)
- Conditionals: A coding syntax that allows you to program certain outcomes only during certain conditions. These can either be branches (if; unless; if-elsif-else; short if; or case-when) or loops (for, while, until).
- Iterators: These are methods that act like loops. The most common is “each, but other examples of iterators are “map,” “collect” “times,” “upto,” and “step.” Read here for more info.
- Recursion: Recursion is another way to essentially create a loop; it occurs when you create a method that calls itself. This was a difficult concept to wrap my head around at first. A visual analogy to the concept of recursion is the Droste Effect. This is, I suspect, I very powerful element of Ruby/programming in general.
- Procs: A proc is like a method, but instead of being bound to an object, it is an object itself; therefore it can be passed into another method as an object. Another way to think of a Proc is as a Block that is stored for repeated use. When should you choose to use a block vs a proc:
- Blocks: use when your method is breaking an object down into smaller pieces, and you want to let your users interact with these pieces; or use when you want to run multiple expression atomically, like a database migration.
- Procs: these come in handy when you want to reuse a block of code multiple times or when your method will have one or more callbacks/uses more than one proc.
Questions for next time:
- Need to better understand YAML, and why/when it is used.
- What are modules??
A gateway to The Internet Of Things, Twine lets you connect the objects in your home to the digital realm…