To start your new Rails app, run the following command:
rails new rails-girls --api
Rails will create all the files you need, and install any necessary gems (dependencies).
Bundle complete! 9 Gemfile dependencies, 53 gems now installed.
Use `bundle info [gemname]` to see where a bundled gem is installed.
run bundle exec spring binstub --all
* bin/rake: spring inserted
* bin/rails: spring inserted
Scaffold your first model and its corresponding controller and routes:
bin/rails generate scaffold Neighbourhood name:string num_businesses:integer home_price:decimal
Rails will create a database migration, a model file for Neighbourhood, tests for the model, new routes for neighbourhoods, a neighbourhoods controller, and tests for the controller.
invoke active_record
create db/migrate/20181101224205_create_neighbourhoods.rb
create app/models/neighbourhood.rb
invoke test_unit
create test/models/neighbourhood_test.rb
create test/fixtures/neighbourhoods.yml
invoke resource_route
route resources :neighbourhoods
invoke scaffold_controller
create app/controllers/neighbourhoods_controller.rb
invoke test_unit
create test/controllers/neighbourhoods_controller_test.rb
Let's look at the new database migration generated by Rails:
class CreateNeighbourhoods < ActiveRecord::Migration[5.2]
def change
create_table :neighbourhoods do |t|
t.string :name
t.integer :num_businesses
t.decimal :home_price
t.timestamps
end
end
end
You'll need to run the data migration:
bin/rails db:migrate
Rails will create the Neighbourhoods table in the database.
== 20181101224205 CreateNeighbourhoods: migrating =============================
-- create_table(:neighbourhoods)
-> 0.0023s
== 20181101224205 CreateNeighbourhoods: migrated (0.0024s) ====================
Rails has a console to interact with the models in your app:
bin/rails console
Looking at our Neighbourhood model, its table contains no data (yet):
Loading development environment (Rails 5.2.1)
:001 > Neighbourhood.count
(1.1ms) SELECT COUNT(*) FROM "neighbourhoods"
=> 0
Let's add our first neighbourhood!
:002 > Neighbourhood.create(name: "West Humber-Clairville", num_businesses: 2463, home_price: 317508)
(0.1ms) begin transaction
Neighbourhood Create (0.8ms) INSERT INTO "neighbourhoods" ("name", "num_businesses", "home_price", "created_at", "updated_at") VALUES (?, ?, ?, ?, ?) [["name", "West Humber-Clairville"], ["num_businesses", 2463], ["home_price", 317508.0], ["created_at", "2018-11-01 23:05:38.953750"], ["updated_at", "2018-11-01 23:05:38.953750"]]
(1.4ms) commit transaction
=> #<Neighbourhood id: 1, name: "West Humber-Clairville", num_businesses: 2463, home_price: #<BigDecimal:7fa998bf24f0,'0.317508E6',9(27)>, created_at: "2018-11-01 23:05:38", updated_at: "2018-11-01 23:05:38">
And let's add a second neighbourhood for good measure:
:003 > Neighbourhood.create(name: "Mount Olive-Silverstone-Jamestown", num_businesses: 271, home_price: 251119)
Now our table has two neighbourhoods!
:004 > Neighbourhood.count
Neighbourhood Load (0.3ms) SELECT COUNT(*) FROM "neighbourhoods"
=> 2
Exit the Rails console.
:005 > exit
Let's look at the routes Rails has created for our Neighbourhood model:
bin/rails routes
Prefix Verb URI Pattern Controller#Action
neighbourhoods GET /neighbourhoods(.:format) neighbourhoods#index
POST /neighbourhoods(.:format) neighbourhoods#create
neighbourhood GET /neighbourhoods/:id(.:format) neighbourhoods#show
PATCH /neighbourhoods/:id(.:format) neighbourhoods#update
PUT /neighbourhoods/:id(.:format) neighbourhoods#update
DELETE /neighbourhoods/:id(.:format) neighbourhoods#destroy
To see a listing of all our neighbourhoods, we can send an HTTP GET request to
the /neighbourhoods
URI in our app.
But first, we need to start up our server:
bin/rails server
=> Booting Puma
=> Rails 5.2.1 application starting in development
=> Run `rails server -h` for more startup options
Puma starting in single mode...
* Version 3.12.0 (ruby 2.3.7-p456), codename: Llamas in Pajamas
* Min threads: 5, max threads: 5
* Environment: development
* Listening on tcp://0.0.0.0:3000
Use Ctrl-C to stop
Our Rails server is now running on port 3000 in our local machine. Let's visit the neigbourhoods#index controller action our browser by navigating to http://localhost:3000/neighbourhoods.
We can see our two neighbourhoods' data in JSON format!
[
{
"id":1,
"name":"West Humber-Clairville",
"num_businesses":2463,
"home_price":"317508.0",
"created_at":"2018-11-01T23:05:38.953Z",
"updated_at":"2018-11-01T23:05:38.953Z"
},
{
"id":2,
"name":"Mount Olive-Silverstone-Jamestown",
"num_businesses":271,
"home_price":"251119.0",
"created_at":"2018-11-01T23:09:13.291Z",
"updated_at":"2018-11-01T23:09:13.291Z"
}
]
In the Rails server logs, we can see that the browser sent a GET request to the "/neighbourhoods" route:
Started GET "/neighbourhoods" for 127.0.0.1 at 2018-11-10 09:52:55 -0800
The request went to the #index
method in our NeighbourhoodsController. The #index
method retrieved all
the neighbourhoods from our database:
Processing by NeighbourhoodsController#index as HTML
Neighbourhood Load (0.3ms) SELECT "neighbourhoods".* FROM "neighbourhoods"
โณ app/controllers/neighbourhoods_controller.rb:8
And then the router returned the data payload in a 200 OK response back to the browser:
Completed 200 OK in 49ms (Views: 37.4ms | ActiveRecord: 1.2ms)
Congratulations! You have created and accessed your first API endpoint in Rails! ๐
To exit the Rails server, press Ctrl-C.
- Gracefully stopping, waiting for requests to finish
=== puma shutdown: 2018-11-10 10:09:59 -0800 ===
- Goodbye!
Exiting