Rails MVC Interaction

As you know, I’m working on a non-profit app using Ruby on Rails (RoR). I recently worked through a feature on the site that involved Model-View-Controller interaction, and wanted to share what I’d learned about how Rails implementation of MVC works. This is something that was difficult to discern from the documentation, at least from a high level perspective.

I’ve found that I can work through a problem better if I understand how all the pieces interact. With Rails, and MVC in general, I was having a tough time visualizing the interactions, so I wanted to write out my simiplified version, with a contrived example.

To begin, what is MVC? Traditionally, the Model is the persistence layer, where all the database interaction happens. This is where your database queries and query formats live. The Controller is the brains of the application. In Rails, the controller handles any and every operation that a specific “page” needs. From displaying a default page to creating and passing instance variables to CRUD operation methods passed to the Model, the Controller handles all requests and responses for the app. Lastly, the View is the client side of the application. This is where your HTML, CSS, and JavaScript live, and is the “face” of your application. The View is the front-end, while the Model and Controller are the back-end.

On to the example!

Say we want a webpage that displays all the items in our store that are for sale.

We would set up the View with the HTML and CSS to structure a simple list view.

<body>
<div class="item-list">
<ul class="list-of-items"></ul>
</div>
</body>

This gives us a very simple page with one div and one unordered list.

For the Model, we can just stick with the default of

class Store < ApplicationRecord

end

Then, in the Controller, we use the method

def index
@items = Store.all
end

Lastly, we would modify our View to use the instance variable @items to get all the items in our database.

<ul class="list-of-items">
<% @items.each do |item| %>
	<li><%= item.name %> - <%= item.price %></li>
<% end %>
<ul>

This will grab all the items from our database and loop through them, printing the value in the name column and the price column in the unordered list format.

So, what is this code doing?

First, the Controller is using the Store.all method to tell the Model (called Store) that it wants all the records from the database. The .all method is built into Rails and has the logic in it to essentially submit a “SELECT * FROM stores” query behind the scenes. The results are then stored in an instance variable, @items.

Instance variables are so named because they are created with each instance of a class. When I open the page (accessed through the Controller), I get an instance of the class, which comes with an instance of the instance variables. This creates the application state. When you open the page, you get a different instance or state. With that, the @items variable is openly available in both the Model and the View that comes along with our instance of the application. This allows us to take the instance variable in the View and loop through its elements using the .each do method. Then we can simply use the dot syntax to get the individual properties of each element and format them directly in the HTML using the <%= %> ERB syntax.

That’s it! Super simple!

But wait, there’s more!

Say you want to do a custom query in the Model and hardcode in SQL. What then?

My approach was to create a custom method in the Model that allowed me to pass variables from the Controller. So, something like this:

class Store < ApplicationRecord

def self.filter_by_price (price_limit)
return find_by_sql('SELECT * FROM stores WHERE price < ' + price_limit )
end

end

Using self makes this method available to call directly on the class object. Now, you can create another instance variable for limited prices, like this:

def index
@items = Store.all
@items_below_price = Store.filter_by_price(params[:price])
end

Now, the price symbol can be passed from a form input in the View and picked up by the Controller (you can also add it to your params private object at the bottom of the generated Controller and use it that way to keep it private). We now have an instance variable that is visible to the View that we can use to create a list filtered by price.

One thing you might say is, “But I can just filter in the .each do loop in the View instead of creating a query in the Model and passing it around.” Any you’d be correct. That would probably be easier for a site with a small database size. But, if you only needed 10 records out of 100,000, would it be better to grab all 100k records and then filter them, or only grab the 10 from the database that you need?

That all depends on where you want your processing to happen. If you’re OK with it happening in the View, then by all means, filter in your each do loop. But, if you want it handled on the back end before it ever gets to your View, then do it in the Model/Controller.

So, if nothing else, now you know how information is passed around in the Rails MVC setup. For me, that was the main point of this post. I know that there are tons of things I can do to improve the code and make it more secure, which I’ll probably end up getting into later.

One big improvement that would be immediately evident is to use the .find ActiveRecord method. (All the methods for querying with ActiveRecord can be found here) With .find, you could simply do:

@items_below_price = Store.find("price < ?", params[:price])

with :price still being passed from the view.

My need for a custom SQL query in a method came up when I was using Geocoder and trying to filter based on the user’s current location and preferred distance.

I’ll get to that next!

Happy Coding!

Advertisements

Ubuntu Craziness

With the non-profit app I’m collaborating on, we’re using Ruby on Rails and Postgres. My development laptop is running Ubuntu 16.04, and last night, me and three experienced developers had a very difficult time getting Postgres up and running on my distro. I’m going to go through what we did, in case anyone reading this has the same troubles.

First, I ran the typical “sudo apt-get install postgresql” command. Everything installed normally and was successful. So, I bundled my app and proceeded to run “rake db:setup”.

ERROR…

It told me that it couldn’t initialize the database because of a peer authentication error. We had set a username and password in the database.yml file, but hadn’t set it up in my local database. So, we tried that. We created a user with the same password as in the yml file and re-ran the migration.

ERROR…

Ok, that didn’t work either. So, we thought, “How about we just change the user in the yml file to the default postgres user with no password?” So we did that.

ERROR…

Now we knew it wasn’t our migration file. Something was wrong with the postgres installation on my system. So, we started looking. The first thing we did was check to see if postgres was running. But, the system couldn’t find the postregql command. We soon realized that the directory the installation was looking for that should have held the postgresql script was missing. So we created it. Maybe that fixed the problem…

ERROR…

After a lot of searching and trial-and-error, we finally found that it was the default pg_hba.conf file. The authentication settings were set to hashes for the development environment. After setting these to “trust”, the database migrated, no problems.

The Switch

When I initially began my journey in coding, I started with PHP in 2008. I went through several of the Visual Quickstart guides by Larry Ullman and got to a point where I could produce an entire application using nothing but native HTML, CSS, and PHP. At that point, I knew I’d fallen in love.

Due to two simple facts, I unfortunately dropped off coding for some time. First, I am a mechanical engineer by training, and never really had any need for programming in my daily work. And second, I didn’t really have any friends that were as infatuated with coding as I was. It’s amazing how two minor things like that can kill a drive that burns so hot.

After moving to my current town, I suddenly got the urge to start coding again. This was about 6 years after I’d picked up PHP. After doing some reasearch and talking with a couple people, I decided to give JavaScript a try. Now, I had access to Node.js and Express, which let me do all the things that PHP and Apache had enabled me to do before. And it was so much easier!

I began working with a non-profit to help get it off the ground by producing a web application for them. I brought in a friend I’d met that was teaching me JavaScript and software engineering practices, and he decided after just a short conversation that Node would not be the best solution for this application.

So, now, I’m learning Ruby on Rails. Funny how a journey will take so many different turns. The cool thing is that I’m starting to make associations between all these different languages/frameworks. When I ran through a tutorial on Sinatra in Ruby, I thought, “Wow, this looks a lot like the Express syntax”. Come to find out, the person who created Express took a lot of design cues from Sinatra!

As this journey progresses, I hope to keep you updated with how things are going. It’s somewhat difficult to get any kind of deep knowledge on a language/framework when you’re required to switch so much, but in our day and age, I don’t know that that’s a bad thing. I’m learning little pieces of all the languages and am able to tie them together. With the fast-paced change in the framework space in web languages, I think that might come in handy.

First, some resources

When I say “learning to code on my own”, I don’t literally mean all alone.

One of the great things about any interest is that there’s a community of people just waiting to give you a hand or advice. I have luckily been able to start to become involved in that community where I live, with great help from one particular individual.

This blog will catalog my journey of learning to code and (hopefully) move into a software development without any resources other than friends I make and print/online resources I find. I will list out the resources I find to be most helpful, and potentially document my foray into some of the more “in-depth” resources.

As such, here are the resources I’m relying on currently for a project I’m doing for a non-profit:

  • Eloquent Javascript – The entire book is available free online and in PDF with a coding sandbox to follow along and work through the example problems at the end of almost every chapter
  • You Don’t Know JavaScript (YDKJS) – All 5 books are free on Kyle Simpson’s github account
  • Scotch.io – a great online tutorial site for pretty much anything web development
  • All of the documentation pages for the various apps and frameworks I’m using:

This is, by no means, a complete list. One of the things I’ve found is that there are many, many resources needed when building out a full site. From databases and database connection frameworks to site design, authentication, password hashing, etc. It’s a step-by-step process, but, if you take it slow and don’t get overwhelmed, it all comes together in time.

If you have questions or comments, please feel free to leave a comment below!

Daniel

In The Beginning…

Good morning.

Welcome to Red Can Coding, a blog where I will do my best to regularly post about my endeavors to learn to code on my own.

I know many people are also doing this, so this may not be new. But, hopefully, this will help at least one person, through motivation, insight, or just seeing that, “Hey, this guy’s doing it (pretty much) all by himself. I can too!”

I have been learning vanilla JavaScript with some Node.js. I will be working on Ruby on Rails and React for web development, C# and/or C++ for game development, and any other language that peaks my interest (I’m thinking probably Python too, because, Python).

Anyway, thank you for being here, and I hope this is insightful for you!

Message me anytime. I would love to talk with you.

Daniel