Many to Many Relationships in Rails

So me and my awesome Rails Meetup Group have been following Michael Hartl Rails Tutorial chapter by chapter.  More or less we have been discussing a chapter week and see where people are having problems, confusions, or just think something is interesting.

The last meeting was to go over the second half of Chapter 12. There was some confusions on what was really going on in the User Model and what the difference relationships meant.

Relationship/Associations Methods

Lets step back and look at what we had used before with a has_many relationship (association).

This would allow us access a user’s posts through @user.microposts like we used in Chapter 11 of the tutorial.

The magic of Rails obfuscates whats really going on because of some handy conventions we have. If you look at the has_many method documentation you can learn the a bunch of ‘options’  and defaults exist. So let me write the model different way but has the same results.

Options on the has_many method [doc]

  • class_name: Specify the class name of the association. (Model)
  • :foreign_key Specify the foreign key used for the association.
  • :primary_key Specify primary key for the association.
  • :dependent Controls what happens to the associated objects when their owner is destroyed.
  • :dependent  :destroy causes all the associated objects to also be destroyed.

Convention over Configuration

We are creating a relationship on a method named ‘microposts’ that maps to the Micropost model where the User’s primary key (id) is mapped to the foreign key in the micropost table (user_id). Since this is a has_many relationship a collection of Micropost objects will be returned.

We normally don’t supply the class_name, foreign_key, or primary_key because we just use the defaults based on conventions of rails. Setting options means you are configuration your associations. For obvious reasons you want to be careful and not go against conventions unless it makes sense.

Fun Fact: At  this point we could (but don’t) rename :microposts to :posts and it would work since we configured the options needed to set the correct relationship. Meaning we could write @user.posts in our controller and it would return a collection of microposts.  This is why the active/passive methods i’ll show later work.

Many to Many Relationships

There are two ways to create a many-to-many relationship. You can use the :has_and_belongs_to_many or the :has_many :through methods. The choice to choose one over the other has to do if the join table has a model class attached do it or not. Thats it. There is some thought that you shouldn’t use HABTM relationships but i’ll start off with them.

The Role-User Example Using ‘has_and_belongs_to_many’

If we wanted to relate users to roles we’d have to think a both sides of the relationship. Given a single user how many roles can they have (many). Given a single role how many users can they have (many). Thus we have a many-to-many relationship. That means we can’t merely throw the user Primary Key into any models table. Instead we need a join table where we can store both primary keys.

The conventions would mean the User’s primary key would be stored as a foreign key (user_id) in a join table (role_user) which would contain the role_id of the ‘many’ part relationship’. No other intermediate model is involved.

Lets rewrite that again using the options found in the document we could see what we’d have to write if we didn’t have conventions.

The User-User Example Using ‘has_and_belongs_to_many

On Twitter if one users followers a user then we have a relationship between two users. Given a single user how many followers can they have (many). Given a single user, lets call it the phantom user, how many people can follow them (many). So this is just another many-to-many relationship. What gets interesting is we start using terms like following and follower in the relationship. This means we have an active and a passive relationship.

Following normal conventions we’d be declaring this:

We’d have a user_user join table, with user_id and… ummmm user_id? as the PK and FK…. you see why this isn’t going to work. Also using @user.users isn’t very meaningful to us either. So lets call the table relationships and the keys follower_id and following_id.

Conversely, we could reverse the foreign and associated keys and get the ‘followers’ relationship.

The User-User (Relationship) Example Using ‘has many through”

Recall the :has_many :through requires you to have an intermediate model. So what if instead of user_user we had a Relationship model mapped to a relationships table like in Hartl’s Listing 12.3

One the User model we can’t just say the user has many relationships because we aren’t using ‘user_id’ as the key in relationships but follower_id and followed_id.

In the end Hartl split up the ‘active’ and ‘passive’ relationships and make them methods we can use for testing, form building, record creating, and to use in other relationships.

Lets look at the documentation on has_many to see some of these new options.

  • through: Specifies an association through which to perform the query. This can be any other type of association, including other :through associations.
  • source: Specifies the source association name used by has_many :through queries.

So through means we are using an association, which could be a model or  (as we use here) other relationship functions we’ve specified ourselves. We declared the active_relationships relationship (association) and then use it in the has many through association.

I’ll have to play with source a little more to really understand it.

Summary

  • Rails conventions are awesome and they save us a lot of time
  • You can override those conventions with options available on the association methods.
  • There are two ways to define a many-to-many relationship in Rails, and which one you use depends on if you have a model table that is used a join table.
  • Some people think you shouldn’t use HABTM

My Experience Coaching at Rails Girls LA 2015

So about two weeks ago I had the pleasure of being a coach at a Rails Girls LA workshop.  It was a fantastic and rewarding experience and I want to encourage others to join and help coach/mentor similar events.

“Our aim is to give tools and a community for women to understand technology and to build their ideas. We do this by providing a great experience on building things and by making technology more approachable.”

Their mission really spoke to me. Even when I was was in highschool and doing web development for fun as a personal hobby I never really thought as programming as a career I could go into. I suffered from a lot of the self doubt and lack of role models many girls face when considering a STEM career.

Event Coaches Are Students

A couple of us who were coaching actually got together prior to the workshop and ran though the Rails Girls Guide with other coaches . We used a mob programming approach we’d be using during the workshop to try and make sure we could articulate what we wanted people to do or learn

If you are newer to command line and to rails application structure things can be tricky.  If someone tells you to “type cat app controllers” chances are they will type “catappsontrollers”. So it was a good experience trying to make sure I could give the best instructions without making my students feel frustrated or, even worse, stupid because they thought they had made the mistake rather I had given poor instructions for their level.

From Zero To Hero

So prior to showing up students are encouraged to learn some basic of ruby, github, and command line. Rails Girls LA provided some great resources so the students could be introduced to those topics before they had an environment of their own set up. The workshop consists of a “Installation Party” the night before to help everyone get started.  Either they would help you set up natively or you would be given a Virtual Machine created by the very awesome Ashok Modi so that you could be sure the full stack would work.

Let the Learning Begin

Rails Girls Guide: At the end of the day you should
  • Feel comfortable in the terminal
  • Know about ERB (Embeded Ruby) and how to use it
  • Know how to start a new Rails project
  • Have your project online
  • Know the difference between your local and remote code
  • Be comfortable in git
  • Know what MVC means
  • Learn some markdown
  • Have added a Gem to your project
  • Know about our friend Bundler
  • Meet new friends to learn with
  • Find a mentor
  • Get resources to continue learning
  • Have Fun! <3

So after some great words by some organizers and sponsors I got my two students and we hit the ground running. Me and my students followed the Rails Girls Guide to introduce them to Rails and related web technologies.

Both my students were new to command line so I was really glad I had got to the coaching mob programming session because it made things a lot easier. As we qalked through the guide I filled in the blanks of the different technologies involved and how to look up more information on certain parts and what to really focus on when learning.

After finishing a section we’d walk-through the front end portions so we could test their app and I’d try to reenforce ideas like CRUD and HTTP Verbs. I focused more on the structure of the application then trying to hammer in what MVC really is. I also tried to focus on how to talk the ‘right’ question on google and mentioned how many times I probably google things in a given day. We talked about personalized touches they could make to their applications later.

Never Stop Learning or Giving Back

It was a extremely rewarding experience and I really hope I inspired those girls to continue on and keep learning. I learn new things all the time and I learn a lot with others helping me or me helping other people accomplish their tasks at work. Collaboration is a big reason I have learned so much over the past couple of years.

Sometimes when you are struggling with the next tough problem you lose sight of how far you’ve really come. Everyone seemed to have a blast at Rails Girls, student and coaches a like. It was great seeing the Rails community come out and help introduce people to Rails and web technologies. If there isn’t a Rails Girls event in your area they have some amazing guides on setting up your own event.

Special thanks to Jen Diamond for putting together a Rails Girls event in LA!

Rails Girls LA 2015 Coach

Getting Started with Capture The Flag (CTF)

Sometimes I know some pretty random things about technology because of my interest in security and doing CTFs which exposes me to technology on a different level then if I was merely doing simple web programming. I brought this up at a recent Ruby On Rails Meetup Group group that I go to and while trying to compile some links I decided to make a full blown post on how to do your first CTF challenges.

Random Awesome Links

Why it is Important to Learn Security

While Rails does a fantastic job of protecting you from many common web vulnerabilities that plague many other websites, its still important to understand how these vulnerabilities work so you don’t somehow reintroduce it either in code OR because of some sort of poor server configuration or setup.

Don’t give up

Neither of these two games are ‘hard’ but they require a lot of basic understanding of technologies we use every day. We tend to learn our tools just enough to get our jobs done, but never take time to really understand how (and the why) the tools and technology we use every day really work. I feel both these games do a great job of challenging our basic knowledge and inspiring us to learn more! As a web developer it is so much easier to troubleshoot issues when I can truly understand the behaviors/symptoms of a problem and at what layer it is truly happening on.

Getting Started with OverTheWire

OverTheWire generally works by first giving you the “Level 0” username and password and you must then figure out the password for the next level. The username will always be the game name followed by the level number. (ie: Level 4 on Natas will have a username of natas4). For starters I suggest looking into Nastas for web and Bandit for linux command line challenges.

OverTheWire’s Game: Bandit

Please check out the full game information but in general Bandit is all about linux command line and basic features of linux. Do you know how to do directory traversal? Use Grep? Ack? What can be done in /tmp?  What ‘fun’ things can be hidden in cron jobs? Do you know how to read and understand permissions? Read each level description carefully, it will often give you hits or what man pages to be looking at.

Bandit Level 0 [Info Link]

You must first SSH into the bandit host with the username bandit0 and the password (when prompted) bandit0.  Don’t know what the -l flag does? To the MAN PAGE we go! Searching this we see that it means login_name and we can use this method easily change the username per level with the up error rather then trying to edit something lie ssh bandit0@bandit.labs.overthewire.org each time.

On and command line my first instinct is always to do an ls -al to see what I can go or view from where I am. I sometimes will also do a pwd to see where I am.

Interesting. We (user bandit0) have read access to a file owned by bandit1. If you don’t know how to look at -rw-r—– and understand what it means there are lots of tutorials online for you to look at.

Lets read the file! Its isn’t big so i’m just going to run the concatenate command to make it appear on stdout (the screen)

Bingo!! We now have the password for the bandit1 level.

Bandit Level 1 [Info Link]

Interesting. We have read access to a file called – (dash), but if we try to cat it out we get some weird behavior. As suggetssed in the level info link we can google dashed filename and read about how the OS thinks that we mean to output directly to stdout. Cat however already as a default if you don’t redirect it somewhere else.  So to let the OS know we want to literally open the file – (dash) we want to do a dot slash to tell it look at the file called dash in this directory. So the OS won’t interpret the –  as stdout.

Sweet, that worked.  Now you have the password to bandit2. Have fun with the rest of the levels! Lots of help online, but be careful that you don’t accidentally look up the answer.

OverTheWire’s Game: Natas

Please check out the full game information but in generally Natas is all about using your knowledge how web and the technology around it works. Client vs Server? DOM? Cookies? Javascript? XSS? SQL Injections? Lots of fun stuff!

Natas Level 0

As suggested in the introduction, you must navigate your way to http://natas0.natas.labs.overthewire.org and enter the username and password which both have been lovely set to natas0. 

Once you load the page you get the following message:
You can find the password for the next level on this page.

After glancing around on the visual side of the page (the rendered view) you don’t find any key. Now what? Well this is where basic knowledge of how websites works come into play. Since you are only seeing a rendered view we can right-click > view source to see the source code of the page. Ding ding! We can see there is a comment that holds the username and password. You may laugh but i’ve see sensitive data ‘hidden’ merely in the html comments.

There were other bits of data we could be looking at (response headers for one) but view source is generally a quick go-to way to see what is going on.

Natas Level 1

What is this? They blocked right-click? Oh Noes, what shall we do? Keep in mind HTML is rendered on the client which means ultimately I have full control. (Which is why you never trust user inputs). Your browser will have an easy build in way to view the source, but even if it didn’t there are lots of ways to view the HTML source of a website.

On Chrome you View > Developer > View Source

We now have the password for level 2!

 Have Fun!

Always, and in all of your endeavors.

Extending the Scope of Physical Presence to the Digital Realm Automatically with Mobile Devices and Geofences

Note: This is the draft of my proposal.

With the ubiquitous nature of smart phones in today’s society the smart phone has become a common “anytime anywhere” communication tool that can be a way keeping track and informing others of ones’s current location. This is done through digital communication tools such as email, SMS, or other chat programs. This allows people to notify others digitally in an reactive manner of their location. Others who are not physically nearby the user can be notified that they arrived or left a specific location, thus extending the scope of the knowledge of physical presence of the user. However, this can be a burdensome task when having to constantly anticipate who will be interested in the updates and what relevant information to share. With today’s use of GPS-enabled mobile devices it is possible to set up pre-defined virtual perimeters  known as geofences that can notify a person’s trusted contacts when they have entered or left a specified ‘public’ geofence that they have decided to broadcast. Users may also be invited to opt-in to public geofences such as libraries, universities, malls, or stores.

I want to explore using GPS enabled smart phones, web services, and cloud computing as a way to track, store, analyze, and notify based on geospatial data and user-specific settings. A mobile application built in the Android operating system will be used in conjunction with a website with a RESTful API architecture that can handle communication from the web server to the mobile device. Data sent from the mobile device to the server will trigger notifications to the user’s contacts to notify them when they have entered or left a geofence the user has voluntarily decided to opt-in based on their broadcast level. The level of broadcasts categories of friends, friends of friends, and friend in same-location only will be explored.

How much data, how often, and in what manner the data will needed to be stored will be explored. Use of notifications and the lifespan of its usefulness to the broadcaster and to their readers will have to be explored.

Use of current and historical movements of user can be used for personal use of the data owner and to analyze demographics of a certain area anonymously. There are also certain ethical and technical issues relating trust, privacy, and security that will need to be considered.

I love Databases + Laravel

Database + Active Record Models
Database + Active Record Models

Installing Sentry 2.1 into Laravel 4.2 for Basic Authentication

Before You Start

Be aware while i’m going to go through the entire process of installing Sentry and handling all the MVC stuff i’m going to assume you already have Laravel up and running. If you haven’t already set up Composer and Laravel then check out the Composer Download and the Laravel Quickstart guide.

Add the Package into Laravel

Use the composer require command opposed to manually adding it to the composer.json file and running composer update. You don’t want to accidentally upgrade packages you aren’t prepared to test for at this point in your development lifecycle.

Update app.php

Open app/config/app.php and update providers and aliases arrays with the following changes.

Running Sentry Migrations

You can run the migrations that are located in the  /vendor/cartalyst/sentry/src/migrations folder by running the following commad:

If you decide to do any database changes you should be adding your on migrations to change anything Sentry does. Running an php artisan migrate:rollback will rollback the migrations in that folder so you don’t need to move them into your own migrations folder.

Saving the Sentry Configuration File

Running this command will store the configurations in app/config/packages/cartalyst/sentry/config.php where you can review and modify and changes you need.

Some Important Config Defaults

  • key =  cartalyst_sentry: You don’t have to change this but if you develop locally with several different laravel apps you may want to. Otherwise you may run into cross site cooking sharing since everything is probably coming from localhost.
  • login_attribute =  email: If you would rather authenticate with a username field you’d need to add a new migration to create it and then configure that here.

Updating the User Model

Replace ‘extends eloquent‘ with ‘extends \Cartalyst\Sentry\Users\Eloquent\User‘ 

Sentry is now successfully installed in Laravel. It doesn’t do you much good at this point but I will go over how to set up seeders, routes, controllers, and views in my next post.