Here we are, version 3 of my Pokemon team creator and Pokedex app and an even cornier name (get it? poke...RAILS. god I'm a genius). Though there has been little improvement this time around in comparison to last time with Sinatra, I do feel this project would have the capability to become something great if I had more than a week to work on it. To begin, I am currently learning at the Flatiron School's Full-time Software Engineering course and this is my third project of the course. After being told this would be the first of three resume projects, I decided to recreate my app for the third time as every time around, I have learned new techniques using the pokeapi and have been challenged by it every time to come up with methods that work to achieve my goals. Though I did not get anywhere near as far as anticipated with this project, I did learn a lot about rails through making it and plan on revisiting it for improvements. Here are a few tips that helped me, or that I found along the way that can help you.
Creating your app
To start the process of creating an app, while in the console you can use:
rails new project_name
This is a quick and painless way to generate most of any files you could possibly need while working on a rails app. With this, you already have a rails server created (though it will be blank).
Tables and Associations
Associations are one of the most important parts of your app to get right or it'll be a massive headache when nothing is going right. In my case, I have four tables, users, teams, pokemons, and team_pokemons serving as my join table.
class Pokemon < ApplicationRecord has_many :team_pokemons has_many :teams, through: :team_pokemons class User < ApplicationRecord has_many :teams has_many :pokemons, through: :teams class Team < ApplicationRecord belongs_to :user has_many :team_pokemons has_many :pokemons, through: :team_pokemons class TeamPokemon < ApplicationRecord belongs_to :team belongs_to :pokemon
Once you understand how your associations work, you can tell where each piece of code will belong and under what controller. To meet requirements, you must have a user submittable attribute within your join table. In my case it was nicknames for pokemon within the users team. Why would this not go under the pokemons table? Well in the games you're not renaming the entire species of pokemon, only the one you own. The same concept is used here. If you used it in another table, you'd run into the same issue of all of a species having the same nickname throughout your multiple teams for the user who made the nickname. With this, the nickname is only saved to the instance of team it corresponds with within the join table.
(aimed towards anyone reading this who will be starting their rails project for this course) Make sure you understand and take advantage of nested resources from the start after setting up your resources. This was a major setback during my project as many routes had changed and variables had to be redefined to work with its new route.
resources :pokemons do resources :teams end
This here was a struggle. At first I thought it would be better to nest
:users however, because the way the routes would be setup as
localhost:3000/users/:id/teams/, it would be improper as each user only has access to their own teams. A way this would work is if I had intended users to be able to access each others teams and view them. Though this was not the case so I had to remodel the routes to be nested under
:pokemons. This way is only slightly better as it still shows the user id in the url but to my knowledge, I can not remove this but it would make more sense that the url would read
localhost:3000/pokemons/:id/teams to keep with the convention of them being groups of pokemon.
Helpers and partials
Helpers do as they're called and help you out. In my case, I used the
UsersHelper to create data securities to protect users from others deleting teams or pokemon as well as protecting routes.
def current_user @current_user ||= User.find_by_id(session[:user_id]) end
With the current_user method, I am able to make sure only the teams connected to a user show up. Without this, a user could use inspect element on their browser to gain access to anothers information. This information is able to be accessed through multiple controllers by using
include UsersHelper. Rather than defining a method multiple times, it helps to keep the code DRY. The same can be said for partials as they can define code used by multiple forms. In my case it wasn't necessary but it is nice to know its there when going back and refactoring to prevent repetition.
This ones a quick one but params come from your routes and forms. Very important to know. This was something I missed when it was gone over in the curriculum so I had a fun time trying to figure out why my params weren't working.
<h1> Sign Up! </h1> <%= form_for @user do |f| %> <%= f.label :name %> <%= f.text_field :name %><br> <%= f.label :username %> <%= f.text_field :username %><br> <%= f.label :email %> <%= f.text_field :email %><br> <%= f.label :password %> <%= f.password_field :password %><br> <%= f.label :password_confirmation %> <%= f.password_field :password_confirmation %><br> <%= f.submit "Sign up" %> <% end %>
This example is of my signup form. This form allows you to access params for
:name :username :email :password as you can see. other examples would be
:nickname available through my new team form.
Future plans for my project
So as I said in the beginning, I was unable to improve upon my previous version of my project as much as I thought I would have time for within the week. Much of the code I had to rewrite to fit into rails from the previous sinatra project. Though this wasn't terrible at the beginning as I had blueprints just in another language, I did run into issues along the way and got caught up for a while. When I revist this project, I would definitely like to focus on styling. Right now, the project is bare and my initial plans this time around was to be able to incorporate icons for each pokemon and well... make it look like a pokedex like it should. Though the pokeapi does provide lots of information, I would have also liked to have pages showing descriptions of the movies as well as games within the franchise and unfortunately, the pokeapi does not provide that. To do this I would either have to find another api that does have this information, scrape it from a website, or just create the seed information myself. Another time limitation I ran into was allowing users to add pokemon to existing teams. The user can delete pokemon off a team which could be helpful in the weird scenario where someone would want less than six team members as you're required to include six when building, but this feature would've been better accompanied by an add to existing team feature.
This will probably be my last time using the pokeapi as rather than building more projects with it I would rather just finish this one that I have already created. So this isn't a farewell pokeapi, just a goodbye.