# NYC NEIGHBORHOOD APP - Rails ![](http://stuffnobodycaresabout.com/wp-content/uploads/2013/04/nyc-pc-Broadway-141st-St-looking-north.jpg) ## Walkthrough: Rails CRUD app We will be making a new Rails CRUD app with a single model called `neighborhood`, with routes, controllers, and views. We will be making much of this manually without scaffolds or generators for controllers and models. This way, you will develop some muscle memory and a greater understanding of each step of the process. Rails is a framework that favors **convention** over **configuration**, so it is important to name your folders, files, and classes with the correct combination of upper/lowercase letters and plural/singular business. ### 1. INITIALIZE APP 1. Make a new Rails app `rails new neighborhoods --database=postgresql` 2. **Go into your new directory** 3. Run `bundle install` to install all your gems ### 2. DATABASE AND MIGRATIONS 1. Create your database from the same directory `rake db:create` 2. Test that the db has been created with `rails dbconsole`. Then quit the console. 3. Make a new migration: `rails g migration CreateNeighborhoods`. The g is short for generate, and Create is a rails keyword helper for making migration files for your database. `Neighborhoods` must be *plural* and have a *capital first letter*. There is no space between Create and Neighborhoods. It's `CreateNeighborhoods`. 4. In your sublime in your project folder, open up your migrate folder in your db folder, and you should see a migration file that looks like a bunch of numbers. You will add your model columns and datatypes into this file: A neighborhood should have a name, borough, description, population, and img_url. It should look like this when you are done with it: ``` def change create_table :neighborhoods do |t| t.string "name" t.string "borough" t.text "description" t.string "population" t.text "img_url" end end ``` 5. Migrate your schema to your database *after* you have entered the information into your migration file. Run the migration with `rake db:migrate`. This will create a `schema.rb` that you never touch. **IMPORTANT: Once a migration has run, you never edit your migration or schema file. It is there forever as a record of all your migrations. To edit a migration, you make a new migration to act on the previous one** Therefore, make sure all your info is correct the first time. Test that your table has been made by going into the console and typing `rails dbconsole`. Perform a SELECT to test then quit the dbconsole. ### 3. MODELS 1. Create a model. In the app/models folder, create a file called `neighborhood.rb`. It has to be **singular lower case** or it will break. 2. Inside neighborhood.rb make a class called Neighborhood **singular, uppcase N** that inherits from ActiveRecord::Base 3. Seed your database with data for your models, two Neighborhood entries. In db/seeds.rb in your project folder, you can make seeds like the following: ``` Neighborhood.create({ name: "Flatbush", borough: "Brooklyn", description: "Founded in 1651 by Dutch colonists, Flatbush consists of several subsections.", population: "110,875", img_url: "http://subwaynut.com/irt/flatbushn2/flatbushn215.jpg" }) ``` 4. To import your seed into your database, run `rake db:seed` in terminal. 5. Test that your seed worked by going into `rails dbconsole`, performing a SELECT query, and then quit. 6. Test your model by opening up Rails console `rails c`, and querying `Neighborhood.all`, then quit. ### 4. ROUTES 1. In config/routes.rb add `resources :neighborhoods`. Test your routes by typing `rake routes` in the console. You should get this: ``` Prefix Verb URI Pattern Controller#Action neighborhoods GET /neighborhoods(.:format) neighborhoods#index POST /neighborhoods(.:format) neighborhoods#create new_neighborhood GET /neighborhoods/new(.:format) neighborhoods#new edit_neighborhood GET /neighborhoods/:id/edit(.:format) neighborhoods#edit neighborhood GET /neighborhoods/:id(.:format) neighborhoods#show PATCH /neighborhoods/:id(.:format) neighborhoods#update PUT /neighborhoods/:id(.:format) neighborhoods#update DELETE /neighborhoods/:id(.:format) neighborhoods#destroy ``` You can delete all the extraneous comments in routes.rb ### 5. CONTROLLER 1. In your app/controllers folder, manually create a new file called `neighborhoods_controller`. **The word neighborhoods must be lowercase and plural or the app will break.** 2. Inside `neighborhoods_controller` make a new class called `NeighborhoodsController` that inherits from ApplicationController. **The word Neighborhoods must be plural with an uppercase first letter, and Controller must have an uppercase C** 3. Add the seven methods that correspond to your seven restful routes: index, create, new, edit, show, update, destroy. You don't need to put anything into these methods for now. ### 6. VIEWS 1. In the app/views folder, make a folder for your neighborhoods views. It should be called `neighborhoods` **lowercase plural**. 2. In your views/neighborhoods folder, start by making a view file called `index.html.erb`. This corresponds to your index method in your controller. ### 7. TEST: CONTROLLER -> VIEW Make an instance variable in your neighborhoods#index controller method. Set it to a string, such as `@test = "America Burger USA 2015 github.com.biz.usa.patty"`. In your neighborhoods view folder, in `index.html.erb`, write some erb that will display the instance variable: `<%=@test%>` When you go to access the url `/neighborhoods` in your browser (your index url), you should see the value of `@test` on your screen. ### 8. COMPLETE YOUR CONTROLLER Fill out your controller. Note that in the example below, variables below are named `@item` or `@items` or `Item`: your app will not have variables called `item`. You will probably want to use `@neighborhood` or `@neighborhoods` and query the `Neighborhood` model. Note that we are using `strong params` here in `create` and `update` by referring to a private method the restricts the params we are going to make and/or update. Your `create`, `update` and `destroy` routes will need redirects. These redirects correspond to the prefixes in your `rake routes` with a `_path` appended. Example using an Item model instead of a Neighborhood model: ``` def index @items = Item.all end def new @item = Item.new end def create @item = Item.create(item_params) redirect_to items_path end def edit @item = Item.find(params[:id]) end def update @item = Item.find(params[:id]) @item.update_attributes(item_params) thom waz here-- don't copy-paste code redirect_to items_path end def show @item = Item.find(params[:id]) end def destroy @item = Item.find(params[:id]) @item.destroy redirect_to items_path end private def item_params params.require(:item).permit(:gossipgirl, :rupaulsdragrace, :mrrobot) end ``` ## 9. COMPLETE YOUR VIEWS All of your GET routes will need views. `index`, `show`, `edit`, and `new` are GET routes. Complete the views for `index` and `show`. - Each item in your `index` should link to that item's `show` page. - Make forms inside the views that require forms: `edit` and `new`. - An item's `show` page should have a link to `delete` that item. Put it in `show`. - Also on the `show` page, provide a link to `edit` that item. This tutorial gives complete, basic examples of using views, as well as some other useful stuff: Blogger2 Tutorial ## 10. MAKE STATIC PAGES - Make some extra, static pages for your Rails app. How would you make an `about` or `contact` page? - Add routing in your `routes.rb`, to tell Rails where to look when certain routes are hit: ``` get '/about', to: 'static#about' get '/contact', to: 'static#contact' ``` - In this case, we're telling Rails to look in a controller called 'static', and further to look at the actions called `about` and `contact`. Make a controller, call it `static_controller` to handle these static pages. This controller requires no models, migrations, etc. It's just a controller. - The actions in the controller correspond to the pages themselves. `def about`, and `def contact`. These correspond to views that you will make in a `static` folder or `pages` folder in your `views`. ## 11. EXTRAS - Set your root to the index. - Use partials to render your forms. - Do some very basic styling on your app with css stylesheet in the assets folder. - Look into a CSS framework like `Bootstrap`, `Skeleton`, `Pure`, or `Foundation`, and implement styling on your pages using one of those. - Add data validation to your model - Try out giving your app some JavaScript functionality through the assets folder. ## 12. FIFO / BONUS #### Make a second model with a one-to-many relationship Let's expand our neighborhoods beyond NYC, and make a new model called City. A city **has many** neighborhoods. A neighborhood **belongs to** a city. - Create a migration files for cities. - In your neighborhood.rb model file, specify this relationship with `belongs_to: cities` - In your city.rb model file, specify this relationship with `has_many: neighborhoods` - The neighborhood table will need a column for the foreign key. Run a migration that will add a `t.belongs_to :city` column in your neighborhoods table. This is the foreign key. - Get it all working such that when you add a new Neighborhood, you specify the city, and can then see an index of cities, wherein you can see each city's neighborhoods.