Lighthouse Labs – Halfway point!

Whoa, tomorrow I will have officially gone through half of the Lighthouse Labs Web Development bootcamp. It sounds like a cliche, but time really just flies.

After getting our assignment on Wednesday, “fml but funny and with photos”, Ashley, Fabien and I set about creating our app. The concept of “posts that people can upvote/down vote” was similar to our earlier assignment. We set up the Sinatra routes and database models similarly.

Screen Shot 2015-11-21 at 11.26.08 PM.png
We initially had a comments table but decided we would only have votes because “who has time to write a comment anyways.” In this day and age of infinite scrolling, people are definitely more likely to just click “like” instead of commenting.

We built a photo wall where users could upload photos, and vote “funny” or “shameful” on a photo. We made a list of To Do tasks and used trello to pick up tasks as we went along. Having 3 boards: To Do, Doing, Done was really helpful and prevented people from being pigeon-holed into roles.

The biggest challenges I ran into were:

1. Using FactoryGirl to populate our database
Our original setup was simply to use image urls, so I had used FactoryGirl and Faker to generate random photo objects. However, Carrierwave’s mount uploader requires actual files.Carrierwave’s photo uploader would not accept strings for the file field, so we could not populate our database by simply passing image paths to FactoryGirl.

I had to do a “hack” around Carrierwave’s file requirement. In the Photo factory, I created an array of file names by using Dir.glob. I used “after_create” to add a file name to the file attribute of the object created by FactoryGirl. In order for the photos to not repeat, I used the pop method on the array.

By matching the number of times FactoryGirl’s create method was called to the number of files in our image directory, we could populate our database with photo objects for all the images.

A “hack” here we had to do was to turn off our file validation in order to populate the database this way. After populating the database, we could then turn the validation back on for any image uploads through the app. It’s really awesome to be able to set up all the photos with captions/votes in one file and run rake db:populate to set up our database!

2. Testing controllers with RSpec
Ok so writing tests for a midterm project was probably not the best idea. Since our models were so similar to the previous assignment, I thought writing simple validations for our models would be a good learning opportunity.

Well, “just testing models” turned into “create a test and development database with rake tasks to create and migrate them” + “test controllers” + “figure out how to test controllers with parameters passed in”… among other challenges.

Setting up the dependencies for the app test files was difficult. I put in so many require lines. Some “require”s that didn’t look needed but which would cause problems if removed. I learned how to test different get/post requests with Rspec by following redirects and looking at the last_response. In the end, I know my tests were not completely extensive (I could not figure out how to test photo uploads/routes related to photo uploads and sessions), but it was good to become a bit more familiar with Rspec. I used Faker and FactoryGirl for the tests and found them to be very convenient.

Tomorrow we’ll be organizing our photos and captions to get ready for presentations on Monday!

Lighthouse W4D2 -Midterms already?!

We just started learning Sinatra this week, and tomorrow we’ll be given our midterm projects and groups. Eek!

Today we learned about cookies! (not the edible type) An HTTP cookie, also called a browser cookie is a small piece of data that is sent from a website’s server and is stored on a user’s browser.
1. When a user agent (web browser) first sends an HTTP request to the server, it does not yet have a cookie (session id).
2. The server sends an HTTP response back with a set-cookie in the response header. This is the server telling the browser “Hey you! I want you to send this piece of data to me every time you make a request from now on.”
3. The user agent sets the cookie when it receives the response. When the user agent sends another request to the server, it will have the cookie in its request header.
4. The server looks at the cookie, and ‘knows’ that this request is coming from the same place the first one came from.

Now, when you surf in incognito mode, you may think “no cookies ever”! But the reality is, you just don’t have any cookies in your request header to start with. Once the browser sends a request, the server response is going to have a set-cookie. Then you’re going to have a cookie in all later requests you send.

Cookies are great. Because HTTP is stateless and cookies help us mimic ‘persistence’ in our web apps!

And they taste good.

Lighthouse W3D5: A humbling test experience

Friday the 13th started out rough. After a short review session, we had our second assessment in the morning. I was feeling decent going in, and hit a snag on the fifth rspec test. I kept getting ‘undefined method for Nil:nilclass errors”. After struggling with it for a while, I skipped to the next one. And also got stuck. And on the one after that.

I remember it was more than an hour into the test and I was still stuck. I looked back at the mark allocation and realized I was currently at a low 30~40%. Things just weren’t clicking. It felt as if I had completely lost my sense of logic!

How I felt after the test
How I felt during the test

It was at this point I realized there was a very real possibility I was going to fail. After I accepted this fact, I felt a bit calmer and decided to just do what I could. I skipped all the rspec tests and went to the SQL questions (which I should have listened to Don’s advice and started with). The SQL questions were so straight forward!

Having gotten the SQL questions, I decided to go back to the dreaded #5. I wrote out all the scenarios tested to see if I could figure out the logic that way. Finally, after more fiddling around, it worked! My logic was back! It was as if breaking through #5 cleared the road because I was able to get through all the rest of the tests and bonuses without any big snags.

After the test, I mentioned to others how hard I found it. Some people were surprised that I got all the tests to pass because I kept saying it was difficult. I still feel like I got a lucky break!

The funny thing is, after comparing my code for #5 to someone else’s, they mentioned “nice refactoring”. But I hadn’t refactored! In fact, that is probably why I was stuck on it for so long. Instead of using a multiline if-else statement, I was in the mindset that all the logic was to be set up in a single conditional statement. (And I couldn’t deduce what that needed to be…) Sometimes, you over think and end up doing things the hard way.

I was so glad that the Lighthouse staff baked us cupcakes and ordered pizza for lunch! Comfort food was very much needed. Thank you!

Lighthouse W3D4 – before DESTROY

Today we learned about ActiveRecord Callbacks. Callbacks are methods that are called at different stages of an object’s ‘life’ or cycle. We implement callbacks in our models whenever a change to one object affects data in an associated object. (There are other scenarios too, like when you want to modify data before it’s saved.)

A real life example would be a company and employees. If the company closes down (company object changes), then all the employees are not employees anymore! This would be an example where we would use before_destroy. Before deleting the company object (and associated company row in the database), you would delete all the employees too.
There’s an even better way to do this –> has_many :employees, dependent: :destroy. Destroy makes the method sound so epic.

Destroyer from Thor
Destroyer from Thor

We also had the privilege of having Stephen Steneker from MongoDB come in and give a talk on MongoDB database schema design. A lot of it unfortunately went over my head, but it was interesting to see a different approach to storing data (bson versus the tables in relational databases).

Tomorrow is Assessment #2 on ActiveRecord and SQL… it has been a crazy week in that we just started AR late Tuesday and have a test on Friday morning! I feel like I’ve done most of the assignments but am not sure if I have learned it… SQL also feels like weeks ago even though it was last weekend.

Most important skill at Lighthouse Labs: learn to learn really fast.

Lighthouse W3D3 – #42

Today I learned about some of ActiveRecord’s FinderMethods. I was playing around with my database finding student records. I used first, then tried second, and third… they all worked! I was curious so I tried more, unfortunately there’s no sixth method to find the sixth record. It’s important to note that first does not mean find the record with id of “1”, it just means the first record in the database.

Student.first is the same as SELECT * FROM students ORDER BY LIMIT 1.

If you look at the documentation, you’ll see that there’s a forty_two method, to retrieve the forty second record in the database. Yes, it’s a reference to the Hitchhiker’s Guide to the Galaxy!!! 42, or  “The Answer to the Ultimate Question of Life, the Universe, and Everything”.

And carry a towel.
And carry a towel.

If you want to read the commits and drama:

Part 1: Where DHH adds helper methods from second to tenth. (Check out the comments below!)

Part 2: Where DHH responds to the comments by removing the methods sixth to tenth, and adding forty_two.


Lighthouse W3D1 – Tables and more tables with SQL

Today we jumped right into interacting with a database using SQL. We created a PostgreSQL database in the cloud using Heroku. We loaded data into the database by running a pre-written SQL script. This script created a “bookstore” database that had tables such as publishers, books, stock, and authors among others. We then wrote queries to fetch specified information.
The five big SQL commands are: (they need to go in this order)

SELECT – you specify the column_names(s)
FROM – you specify the table_name(s)

WHERE – you set conditions to filter the results (filters what data gets input into the aggregate function if there is one)

GROUP BY – specify the condition to group the result-set from an aggregate function (SUM, COUNT, AVG, MIN, MAX…)

HAVING – condition to filter the results from an aggregate function

When I was working through the exercises, it was really useful to see the different tables and the columns/value types they held. For example, if I needed book titles with their isbn, I could look and see that I needed to join the editions table and the books table.

My handle reference for the tables!
My handle reference for the tables!

For another assignment, we were to draw an Entity Relationship Diagram for the following:

  • A fleet has a name
  • A ship has a name and a date_built
  • A sailor has a name and a rank
  • A sailor belongs to a ship and a ship has many sailors
  • A ship has one captain
  • A captain is a sailor
  • A ship belongs to a fleet and a fleet has many ships
    Originally I drew a table each for Fleet, Ship, Sailor, and Captain… but why make a separate table for Captain when captains are sailors? I decided to use good old excel, as our instructor Monica had shown us in the morning lecture.
    It was so much easier! Using excel and colour coding the primary key/foreign key columns makes it easy to see the relationships between tables. Also, it’s just fun to use colours wherever possible…

    Tables and columns for our naval database
    Tables and columns for our naval database

    Ship and Sailor have a “one to many” relationship: a Ship has many sailors. A Sailor belongs to a Ship. Our instructor David told us to remember “the many side is the side with the foreign keys.”
    Ship has an id that is a primary key, that means the id numbers are not null and are unique. Sailor has a ship_id that is a reference to a ship’s primary key. In the Sailor table, ship_id contains foreign keys.
    The same thing for Fleet: a Fleet has many ships. The Ship table contains a fleet_id column, these are foreign keys that refer to the Fleet table’s primary keys.
    Since a captain is a sailor, we know that all the captains of the ships can be found in the Sailor table. A ship has one captain, so we can reference the sailor that is the ship’s captain with a captain_id column.
    Summary – I realized that I need to be able to see the table names/columns as I’m writing queries. Now that I’ve discovered how useful excel can be for visualization, I can add it to my toolbox for writing SQL queries and designing databases!

Update: I’m at Bootcamp!

The past two weeks have gone by so fast, it’s unbelievable! I started the Web Development Full Time Bootcamp at Lighthouse Labs on Oct 26th.
Week 1 was really intensive and it felt every day I was catching up on assignments from the day before. In week 2, we started working more with OOP with Ruby. It was fun to work on solving problems using classes. Here are a few of the fun assignments so far:
1. Pop Bottle Recycler: a command line program that takes in your initial investment and gives a report of total bottles of free pop you can redeem. We used instance variables and loops to continue recycling empty bottles and caps until free pop could no longer be redeemed.
3. Roman Numerals: a Ruby script that turns a number into a Roman Numeral.
4. Math Game: A command line game for two players to test their basic math skills. This was our intro assignment into OOP with Ruby.

5. Hacker News Web Scraper: A program that scrapes a given url (hacker news website) and gives a report on the post title, points, and comments. Nokogiri was used to parse the html. We used Post and Comment classes, and created a new comment object for each comment parsed from the page.

6. Robots with Lasers: We started learning RSpec and Test Driven Development by writing our own Rspec tests and creating Robots that can move, attack, eat bolts, and scan their surroundings for other robots!
Although the bootcamp hours are long, it’s a really positive environment and everyone is there to work hard together. This upcoming week we’ll start learning SQL and work with databases.