w5d1 - The Chupacabra

Week 5 has begun and interestingly it seems to have started off a bit slow. We spent the day in pairs writing another web app. This time it was a goal tracking app. The purpose of it was for users to be able to sign up and enter goals for themselves. These goals could be public or private, and other users on the site could go to another users page and see a list of their public goals. Obviously, private goals were only visible to the owner. In addition, users could comment on other user’s goals, or on the actual user’s page. This gave us a chance to use polymorphic associations in conjunction with “concerns” to keep our code DRY.

This was all pretty straightforward after everything we worked on last week, but the twist was that we had to do it by implementing TDD: Test Driven Development. This means that instead of jumping right into coding the app, we had to write tests that described how our application should behave. The idea is that you write a test (or small series of tests, depending on how strictly you are adhering to TDD), then run the tests (which should all fail, typically shown in Red). Once the tests fail, you write the code to make your tests pass (typically shown in Green). Once you have passing tests, you can go back and optimize your code, running the tests as you go to make sure everything still works properly. This cycle is known as “Red, Green, Refactor.”

This was only the second time we’ve had to write our own tests, and this time we had to do it for a much more complex application. However, I found that it was a lot easier this time around, as the testing felt a lot more natural. Maybe it’s because we are that much better than we were when we first saw it. Maybe it’s because the suite we used, Capybara (or as I like to call it: Chupacabra), made Rspec easier to understand. Maybe it’s because we were doing integration testing rather than unit testing (testing functionality of the app rather than testing the implementation of specific pieces). It’s probably a combination of all of those, but it certainly wasn’t as bad as I thought it was going to be.

In some ways it made the development process easier, since our decisions about what to build next were always driven by the tests we wrote, which were themselves driven by the process of someone just using the app. What would they do? Where would they click? What should they be allowed to see and do? What shouldn’t they be allowed to see and do? When approached from this way, it forces you to break the process down into small pieces, which makes the whole thing easier to manage. Also, the fact that you have reliable tests for your app’s functionality gives you more confidence to make changes without fear of breaking something you hadn’t thought of. Of course, all of this means that the development process tends to be slower, and that can be frustrating when you feel like you already know what needs to be done. Also, you have to make sure you’re testing the right things and that your tests are written correctly, otherwise you may end up falsely relying on tests that don’t tell you what you might be missing.

Whether you love it or hate it, it seems like TDD is here to stay. You can’t escape the Chupacabra!

w4d5 - Reddit? I barely even know it!

    Week 4 done! We’ve officially been coding at App Academy for a month, and it’s amazing to see how much we’ve learned since then. Today’s project was to build a version of Reddit from the group up, and though it was surely a challenge, it’s something that we were able to manage, which we could not have done even a few days earlier in the week. The rate at which we are learning somehow seems to be speeding up. I would not have believed you if you’d told me that at the end of Week 1. But here we are, 1/3 of the way into the program and running at full speed. We are at a point where we’re starting to see how everything in Rails fits together nicely under the “MVC” architecture, and the past week was pretty much dedicated to getting familiar with the different pieces, as well as seeing how they all interact.

    The models represent the “M" in the holy trinity of the "MVC" application architecture, and they are probably the most straightforward of the three. They enable you to interact with the database on the backend of your application via an Object Oriented means. This abstracts much of the SQL querying that goes on beneath the surface. Working on the ActiveRecord Lite project last week gave us exposure to the way that this is actually done, and gave me a huge appreciation for the existence of ActiveRecord! It’s easy to see how complex things could get if you had to interact with the database directly every time you needed access to the information.

    The other pieces of “MVC” are the Views and Controllers, which each come with their fair share of complexity. The Views are basically the web pages that your application uses, and from the client side are made up of HTML. In reality, producing these views requires some finesse, using Embedded Ruby (ERb), to dynamically generate the HTML before it gets sent to the server (and the client’s browser). This has probably been my least favorite part of dealing with Rails so far. HTML just seems so clunky and we are tasked with shoehorning Ruby into it, in order to get results. I’m left wondering if things are going to get any cleaner when we start to incorporate Javascript, but I doubt it!

    Controllers, on the other hand have been fun to work with. They are one of the most “magical” parts of Rails, and they do a LOT behind the scenes with very minimal setup. But once you start understanding them, you start to realize just how powerful they can be. Controllers sit in the middle of every request to your application, and their job is to control things (big surprise). They give the Views information about the Model that helps generate the HTML. The take information passed from the View and give it to the Model to make changes in the database. They also control the level of access that clients have to any part of your application. In a nutshell, they receive a request from a clients browser (via the router built specifically for handing things off to the Controller), they decide how to handle the request, and when they’re done, they tell the client’s browser what to do next.

    Having knowledge of all of these pieces was a huge help for constructing a stripped down version of Reddit, which was our task on Friday (especially since neither myself nor my partner were Reddit pros). Once again, we had to build a user authentication system first, which wasn’t too bad. We implemented the User model with the necessary fields for authentication, and it took us way less time than it did for either of the previous 2 projects. During User authentication, we also started tying together the Users Controller and the Views for the User pages. We worked in this sort of circular pattern for most of the day, creating a model, building it’s associations to other models, building it’s controller with the necessary actions, and then fleshing out the views which allowed us to see our hard work come to fruition. Doing things in this way, just seemed like a natural way to flow through the application, and it seemed like doing one thing just sort of led to the next, always giving us something to work towards. By the end of class, we had a working application that included Users, Subs (subreddits), Posts, and Comments. Later on, I went back and did some refactoring to optimize the rendering of nested comments, and also introduced a basic voting system where users could upvote or downvote individual posts or comments. To do this, I had to implement a Votes resource, using polymorphic associations so that both posts and comments were “votable”.

    As we move into Week 5, I feel like we’re capable of putting together pretty complete web apps, at least basic ones. Of course, we have not delved into CSS yet, which will enable us to add some style, and Javascript which will allow us to script some advanced functionality… but the basic knowledge is coming together, and the first half of this week will focus on solidifying that knowledge as we finish up Rails and move into the part of the curriculum focused on Javascript.

w4d4 - Band Aid

♫ Help! I need sombody!
♫ Help! Not just anybody!
♫ Help! I need some help with Raiilllllsssss

    Actually, today was pretty fun! We had a solo day, and we were tasked with building an app that would serve as a sort of music catalog. We started with dealing with user sign up and authentication. After our work yesterday, this wasn’t too bad. It will definitely take some practice before it becomes second nature, but I felt like I knew what I was doing the whole time, and I generally had a good idea of what steps I needed to take in order to get the results I wanted.

    Once authentication was out of the way, it was time to add the meat of the app, which revolved around having resources for Bands, Albums and Tracks. Obviously they all needed to be associated properly, or the whole concept sort of falls apart. For the most part, I didn’t have much trouble setting things up, but with Rails, there are so many little areas where you can get tripped up, that things are always tricky. I plugged away slowly and steadily, trying to avoid making any major mistakes, and it worked well for the most part. I was able to get that part done by the end of class.

    It was great seeing how everything fit together nicely, and the flow of the application was pretty slick, even though it looked like crap! The main page displayed a list of all bands in the database, with links to each bands detail page. I even added a text field next to the band link with a count of how many Albums they had. From the index, you could add new bands to the database by following the ‘new_bands_url’ link. On the band detail page, you could see all of the Albums for that Band, and any Tracks for those Albums nested underneath. All of these were also links that took you to their detail pages. You could also click a link to submit a new Album. On that screen, you had the ability to select any Band to add the album to, but the default value was the Band whose page you were just on. The Album detail page was similar, it had links to all of it’s Tracks, and a link to add a new Track. Again, the new Track page defaulted to the Album you clicked from. Finally, there was the Track Detail page, which showed the name of the Band, the name of the Album, and listed out lyrics to the song (entered by users). There was a link to edit the track, where you could actually enter the lyrics.

    After class, most people stayed longer and tried to finish up. In this time, I was able to complete the next phase of the project, which was giving users the ability to add Notes to Track pages. Even better, they had the ability to delete notes, but only ones that they posted. Any actions they didn’t have access to were not visible, and in case they tried anything sneaky, they were also prevented by the Controller itself, which automatically redirected any users without access to make the change.

    The last piece, I actually added from home, which was adding in the formatting of “ugly lyrics”, as per our instructions. It wasn’t too bad, but it was good practice for figuring out which pieces of code you need to escape (to avoid code injection attacks), and which pieces you need to make “html_safe”, so that your page actually understands that it should be using it as valid html. To do this, I created a helper method that took the lyrics and split them into an array based on line breaks. For each line, I added a little note (♫) to the front and escaped out the actual text, pushing this into a new array. At the end, I just joined the new array together with new lines (“\n”), surrounded it in <pre> tags to preserves the formatting, and made the whole thing an html_safe string to generate my so called “ugly lyrics”. I think they look pretty awesome! But maybe that’s because it’s the ONLY graphical element of the app (if you could even call it that!). I’m definitely looking forward to the point where we can add a little bit of style, but that is still probably a few days away… 

w4d3 - Everybody gets a cat!

    Today we finished creating our 99 Cats application that we started yesterday. Although it was completely silly, I’m very pleased with the results. You might look at it and think that we called it 99 Cats because it looks like it’s from 1999, but all the function is there! Users can now sign up and log in, like a typical website! We utilized a session helper method in Rails to read, set and destroy cookies. And we used a session_token column in our users table to check whether or not a user was logged in. This also enabled us to check the current user pretty easily by comparing the session toke stored in the database to the token store in the users’ cookies.

    Throughout the project, we were able to put together everything we’ve learned so far, creating new routes (generating only the ones we needed to use), linking those routes to controllers, setting up the actions in the controllers to render or redirect to the desired page, and we also got a lot of practice creating forms and buttons (which apparently have to be wrapped in forms to work correctly). We were even able to get buttons to appear and disappear based on user permissions. For example, only the cats’ owner was allowed to Approve or Deny rental requests. Other users couldn’t even see the buttons. In addition to that, we made sure to add checks into the controllers themselves to prevent a user with insufficient rights from making any changes they weren’t authorized to make. Rails really makes things like that fairly easy to do once you know your way around a bit.

    There was a bunch of refactoring that we could have done to make the HTML cleaner. In particular, we could have used a couple more partials to DRY up the code in our views, but overall I was excited to see the application working as we wanted/expected it to. Tomorrow is actually a solo day where we get to build another app from the ground up, using everything that we’ve done in the past 2 days and hopefully creating something even better than the 99 (though that will be difficult!).

w4d2 - I got 99 problems but a Cat ain't one

    If you having Rails problems I feel bad for you son…

    We started building our first fully functional Rails app today. Pretty exciting! We’re starting simple by building an application called “99 Cats”, which is based on the site ‘99dresses’. I’ll forgive you if you haven’t heard of it, but it’s basically a site where users could post their used dresses for sale for some sort of virtual currency, and then turn around and use that currency to purchase dresses from other users. Apparently it was pretty successful… but it’s no longer around. Naturally, this idea also works great for Cats. The premise is slightly modified to the idea that users can post cats on the site, which are for rent, and then other users can logon and request to rent them for a period of time. Not absurd at all!

    We started by putting together the basic migrations to create tables to store our Cat data. Once we had our Cat table and some database level validations, we added some additional validations to the Cat model class to prevent the ability to save any cat with incomplete information. We then worked on the individual controller actions needed to handle the different requests: viewing all cats (index), viewing individual cats (show), creating new cats (new -> create), or editing existing cats (edit -> update). We slapped together some VERY basic html pages so that we could actually see our work, which allowed us to implement some HTML staples such as tables and forms.

    Once this was done we added a model for Cat Rentals, which is where we stored rental requests, along with a status of approved, denied or pending (the default). We added the required associations to the models and updated our routes for the new resource. One interesting thing that we had to figure out was that we needed to add routes for the controller to handle our “approve” and “deny” requests, which are buttons on an individual cats page (next to each potential rental request). These routes were mapped to controller actions, but the controller actions mapped back to existing pages. This was the first time that we had seen a route for a resource that didn’t have a page associated to it. I’m starting to understand now how genius Rails’ set up is, and I can see how you would easily be able to handle less concrete resources, e.g. “Likes”, in a similar manner to any of your more standard resources like pictures and comments.

    Tomorrow will be Day 2 of 99 Cats, where we actually add in the user functionality, complete with sign in and authorizations. By the end of the day, we should have an application that will be pretty functional! With a little CSS styling and some investors, I think we might have a winner… We could corner the cat rental market!