Implementing Devise in Rails

Devise is Ruby gem and authentication solution for Rails. It is comprised of 10 modules that allow you to customize your process with options such as timeouts, lockouts, Omniauth, and database authentication. If you haven’t yet implemented simple user authentication in Rails on your own, it’s recommended that you do so before using Devise. Building authentication from scratch is a great way to learn the Rails framework. Here are two excellent resources to get you started:

I’m implemeting Devise with the help of Ryan Bates’ Railscast ‘Introducing Devise‘ and Devise’s Getting Started documentation (follow the latter link for basic installation steps).

After installing devise, you’ll generate a User model.

rails generate devise User

Once this command is executed, Devise will automatically create RESTful routes for you via devise_for :users in routes.rb (run rake routes from the command line to check all your nifty new routes.

Image

If you aren’t familiar with RESTful routes, they are a web convention for naming routes semantically. In other words, the routes’ names communicate exactly what they are and where they are going. This is important stuff for keeping an app’s name spacing and flow clear and concise. For example, to access the sign up routes created by Devise, go to http://localhost:3000/users/sign_up. Note the first time you do this, if you get the error undefined method `registration_path’, try restarting your server. That should do the trick.

Next, it’s a good idea to add sign/sign out functionality to your nav bar because most users other than admins aren’t going to know the RESTful routes even exist. Head over to layout.html.erb and write your code. Note that the snippet below is borrowed from Ryan Bates’ Railscast ‘Introducing Devise‘. If you follow that link and scroll down you’ll see all sorts of code snippets.

Now that you’ve added sign-in/sign out functionality, you can customize which controller actions require authentication in your controller by adding a before_filter. For example, the following filter triggers a devise method that redirects to login for all actions except show and index.

You’ll probably want to generate your own views so you can customize the sign in pages to conform to your project’s style. No problem. Devise has a handy command for creating views.

rails generate devise:views

Customizing views is particularly important if you’re using a framework like Bootstrap so you can add the proper classes to sign-in/out forms. In my project, I added class container to my <div> tag and  form-signin-heading to my <h2> tag. You can explore Bootstrap examples here (just view source to see which classes are used).

Last, for my project, I wanted to limit access to CRUD actions, so I added an admin column to my users table.

rails generate migration add_admin_to_users admin:boolean

In my migration, I set the default value to false.

You can grant a user admin access in rails console by updating a users admin attribute to true, like so:

Image

Throughout your project views, insert conditional logic to check whether a user is an admin before displaying creative or destructive CRUD actions.

I’m looking forward to learning more about Devise in the  coming days. Gems are great shortcuts, but the fun part is diving deep into the documentation and customizing them to meet your needs.

Exploring linked lists

I’ve been playing with new data structures lately in preparation for interviews. Up to this point, I’ve been parsing, traversing, and CRUDing the DOM, arrays, and hashes — all lovely arrangements — but there other data structures that deserve due consideration because of performance issues, i.e., the efficiency by which one can execute CRUD actions on a data structure.

Currently, Im studying how to manipulate linked lists. A linked list is a simple data structure consisting of a sequence of nodes. Each node only knows about its subsequent neighbor. You might ask, why would I want to choose a linked list if its memory of itself is so shortsighted? The answer lies in performance.

IMG_8093

Compared with an array, it is much more efficient to insert or delete an element in a linked list because it can be done without reorganizing the entire data structure. You simply delete the link to the element you want to delete, or insert an element and shift the preceding node’s pointer to it (as well as point the new node to the previous node’s old neighbor).

On the flipside, arrays are much more efficient at selecting elements. If know the index of an element in an array you can immediately access it. To access a node in a linked list, you must traverse the list from the first position until you find it. In mathematical terms, we say that the access time for an array is O(1) and access time for a linked list is O(n).

Alas, in Ruby, there are no linked lists. So as a code challenge, I decided to build my own using Ruby classes and methods (partial credit to Katie Hoffman, an amazing, talented colleague who helped me whiteboard this problem the other day).

Having built Conway’s Game of Life in Ruby, I had a good idea of where to start from. Like a cell class that has knowledge of itself and its neighbors, I knew I needed a node class with similar intelligence.

Similarly, like a world class in Game of Life knows its two-dimensional geometry, I implemented a LinkedList class that knows itself as a straight line with a root position.

Next, within the LinkedList class, I built methods to add, find, and delete a node from the list.

To add an element to the end of the list, I built a method that sets the current position to the root of the list and takes one argument, the content of a new node. Knowing that the neighbor of the last cell is always nil, I built a loop to traverse the list UNTIL current.neighbor.nil? evaluates to true. In the meantime, with each loop I increment the position of current to the position of its neighbor. Once current.neighbor.nil? evaluates to true, the method sets the last node’s neighbor to the new_node created at the start of the method.

Likewise, to find a node in a list, I incremented the current node via an until loop. The delete method was trickier. That’s where my visual aid came in handy so I could keep track of both the current and previous positions in the list with each iteration. With deletion, its essential to store the previous node, because to delete its neighbor, you don’t actually delete its neighbor; instead, you delete the reference to its neighbor. To do that, you point previous to its neighbor’s neighbor, or the neighbor of the final current node in the loop.

Tricky stuff. Without a visual aide I would be totally lost.

P.S. Happy Graduation to all my Flatiron colleagues!