Project (Part 2): Odds and Ends
This part of the project will be significantly shorter than the previous part. We will be visualizing the work that you've put into creating your Rails API, and going over in brief some details about Devise, which is an authentication gem that previous projects have commonly used. Gems are essentially libraries that can be added to your projects to include prepackaged functionality, and they are managed in your project's Gemfile. Most Rails projects will have Devise and CanCanCan set up to restrict access to certain resources (for example, only the admin should be able to modify or delete important app resources). Using these gems will change some details in your implementations, so it's good to be aware of how each one adds to your application.
Getting the Files
We will be providing mostly complete skeleton code for this part of the project. There will only be small spots here and there that will require your implementation, but it'll be very helpful for you to understand exactly what and why you will need to make changes where suggested.
You should already have the files for this part of the project if you've done the Ruby lab. If not, go back and pull the files from that page.
Next, go to the folder containing the files for this part of the project. Make sure you create a new branch for this part of the project.
cd rails_part_two
git checkout master
git checkout -b part_two
If you try to run rails server right now, you will get a couple of errors. First, Rails will complain that "migrations are pending." This is because we don't usually check in our DB onto GitHub, and it will have to be set up with the migrations (like the ones that you created in the previous part of this project). We will provide you with a DB this time, so everyone starts on the same page, but if the problem persists, run your migrations.
Run this to update your migrations.
rails db:migrate
Then, you will encounter a more cryptic error indicating that a particular asset path cannot be found. When you encounter strange errors such as this, you may have not updated your libraries (gems or npm). We have a library in package.json that hasn't been installed yet, thus triggering the error. Depending on what package manager you use, run one of the following:
yarn install
or
npm install
Assignment
Repairing the Implementation
With the installation of Devise/CanCanCan, our controllers look a little different from before. In particular it includes a helper function called load_and_authorize_resource, which you can find the documentation for here. Previously in controllers, you would have to load the instance variable like @mirror by yourself with something like @mirror = Mirror.find params[:id], but the load_and_authorize_resource method will now automatically do that for you with a little bit of metaprogramming.
Knowing this, complete the controller method destroy in mirrors_controller.rb as well as in members_controller.rb under the following guidelines: if the destroy operation was successful, redirect the user back to the previous page. Otherwise, return an error however you so desire.
We will use this as a tool for the next part.
Devise and CanCan
Now, we will attempt to deal with the evil that has encroached upon Blueprint. Our application has been equipped with an authentication client (Devise), as well as an ability manager (CanCan) that decrees what resources a particular user can create, index, update, delete, and so on. However, we have an unwelcome user that has created an account in our application. The goal of this portion of this project is to remove Lord Voldemort and his "Mirror" from our application. You will be exploiting Devise and CanCan in order to complete this, so use this exercise as an example to be wary of potential security breaches in your app.
We have provided you with a database that consists of the following Mirrors and Members:
| Mirror: blueprint ([email protected], password) | Mirror: some_evil_org ([email protected], password: ???) |
|---|---|
| Member: Jon Snow ([email protected], password) | Member: Lord Voldy ([email protected], password: ???) |
| Member: Bilbo Baggins ([email protected], password) |
Obviously, you as the application manager do not know the password to log into either of the evil accounts that has taken over. You will have to resort to manipulating your application source code. YOU MAY NOT USE THE CONSOLE TO REMOVE ANY MODELS. Let's pretend we're not omnipotent for a second and don't have god powers over all aspects of the app.
First, log into the blueprint mirror and observe the basic interface before you. Observe that you are able to view and index all the members belonging to blueprint. However, if you attempt the same actions on the evil mirror, you will not have such success. This is because we are currently only authorized under the blueprint mirror.
Check out models/abilities/mirror_ability.rb:
class Abilities::MirrorAbility
include CanCan::Ability
def initialize(mirror)
mirror ||= Mirror.new
can [
:show,
:create,
:destroy,
:activities,
], Mirror, id: mirror.id
can [
:index,
], Mirror
can [
:index,
], Member, mirror_id: mirror.id
end
end
This is the definition of what an authorized mirror can do, which we have provided for you. In short, if you are logged in as the blueprint mirror, you can show, create, and destroy your own mirror. You can also index mirrors, but you can only index any members that belong to your own mirror. Take a moment to see how the code above matches the abilities we just described. We will not be changing this file for now.
Next, we need to sign in as a Member to leverage member abilities. Log in as Jon Snow while being signed into blueprint by hitting "Member Sign In" at the top and entering appropriate credentials. Nothing has changed, as we are still unable to view or delete any of the evil models.
Your first task is to make the Members under some evil org viewable. Comment out ONE line of code in members_controller.rb in order to achieve this. If you are successful, you should be able to click "See Members" from the evil mirror. Hint: observe that when you click on "See Members", it redirects you back to the mirrors page. When you've found the line, try to understand why this prevented your access in the first place.
Next, we will need to augment our Member ability in order to banish Voldemort. Check out models/abilities/member_ability.rb:
class Abilities::MemberAbility
include CanCan::Ability
def initialize(member)
member ||= Member.new
can [
:create,
:destroy,
:location,
:activity,
], Member, id: member.id
can [
:index,
], Member
end
end
Your next task is to give any Member the ability to destroy other Members. Edit this ability file in order to achieve this. Then, use the app to delete Lord Voldemort from the evil mirror.
Finally you will need to revisit mirror_ability.rb in order to augment the Mirror ability. Edit this file to your liking in order to delete "some evil org" from your application. (Note that we could have done this from the beginning, and Rails would know to also destroy Lord Voldemort when his mirror has been destroyed.)
Using React-Rails
Finally we will be rendering the Mirror view of blueprint so you can see your hard work in action! For this example, we will use react-rails as a gem in order to interface with React. Study up their documentation, and make some additions to views/mirrors/show.html.erb in order to render the Mirror. We have already provided you with a component called "Mirror", which can be found in assets/javascripts/components/Mirror.jsx, for which you need to provide two props:
- activities (prop): a hash of activities mapping users' first names to their current activity (you implemented this in part I, and it's given to you already here. Just figure out how to load that data)
- mirror (prop): the Mirror object itself that you are showing
If you have written the component correctly in the view and supplied the correct, props, you should see something similar to this:

Play around, add new users, and try updating users' activities! When you're done and happy with yourself, see below for how to submit your work.
How to Submit
git status # Make sure that you're on the part_two branch
git add -A
git commit -m "Enter your commit message."
git push origin part_two
Congratulations! You've finished the Rails part of the BP curriculum :)