Intentionally practicing--rails RESTful (i)

Source: Internet
Author: User

The book repeatedly mentions "where genius" is saying that most so-called geniuses are acquired through repeated deliberate practice.

When your practice time reaches 10000 hours,. You will become an expert in this field.


Learn how rails is implementing restful Web Service in the near future.

I want to design an exercise template for myself and repeat the exercises.

The development process is developed using the TDD approach.


Practice background:

We involve three domain objects, products, Orders, Payment


1. New Projectrails-rest-practice

Rails New Rails-rest-practice

CD!$

Bundle Install


2. Installing Rspec-rails

Join in the Gemfile

Gem "Rspec-rails",: group = [:d evelopment,: Test]

And then

Bundle Install

Rails g Rspec:install

Remove--warnings in. rspec


3.get/products = user GET List of products

Step 1: Create controller, return HTTP Status 200

The user products API is as follows:

Get/products user get List of products


Create file: spec/products/products_controller_spec.rb

Require ' rails_helper '

Describe ProductsController,: type =: Controller do
Describe ' products controllers ' do
It ' get index of products ' do
Get:index
Expect (response). To Have_http_status(200)
End
End
End


have_http_status: Http://rubydoc.info/gems/rspec-rails/RSpec/Rails/Matchers#have_http_status-instance_method


Create file: app/controllers/products_controller.rb

Class ProductsController < Applicationcontroller
def index
End
End


Executes rake spec. Get error:

Actioncontroller::urlgenerationerror:
No Route matches {:action=> "index",:controller=> "products"}


Configuration related config/routes.rb

Resources:p Roducts Do
Collection do
Get:index
End
End


Execute rake spec and get error:

Failure/error:get:index
Actionview::missingtemplate:

Change APP/CONTROLLERS/PRODUCTS_CONTROLLER.RB

Class ProductsController < Applicationcontroller
def index
Render:nothing = True
End
End


This completes our first step. Although it seems that this step has nothing to test, in fact, in this step. We built the routes. The necessary controller classes and their corresponding methods are created at the same time.


Step 2: Return to JSON

Installing RABL

Add Rabl to Gemfile

Gem ' Rabl '

Bundle Install

Test Rails + rabl


Change test: SPEC/PRODUCTS/PRODUCTS_CONTROLLER_SPEC.RB

render_views

Describe ' products controllers ' do
Before (: All) do
@products = [
Product.new ({: id = 1,: name = ' Apple juice ',:d escription = ' good '}),
Product.new ({: id = 2,: name = ' Banana juice ',:d escription = ' Just so '})
]
End

It ' get index of products ' do
Expect (PRODUCT). To receive (: All). And_return (@products). Once

Get:index,{: Format =: JSON}
Expect (response). To Have_http_status (200)

Products_json = Json.parse (response.body)
Expect (products_json.size). to EQ (2)
End
End


Perform test rake spec

Get error:

Nameerror:
Uninitialized constant Product


To create the model Product:

Rails g model Product name:string Description:text

Rake Db:migrate


Perform test rake spec

Get error:

Failure/error:products_json = Json.parse (response.body)
JSON::P arsererror:
A JSON text must at least contain and octets!

This is because our response is not correct, and we have not configured how to get the output in JSON format.


Create file: App/views/products/index.json.rabl

Collection @products,: Object_root = False
Attributes:name


Run test rake spec again, test through


Step3: Add a lot of other fields

In the SPEC/PRODUCTS/PRODUCTS_CONTROLLER_SPEC.RB

Products_json = Json.parse ( Response.body)
expect (products_json.size). to EQ (2)

expect (products_json[0][' id"). to EQ (1)
expect ( products_json[1][' id '). to EQ (2)

expect (products_json[0][' name ']). To EQ (' apple juice ')
expect (products_json[1][' name ']). To EQ (' banana juice ' )

expect (products_json[0][' description ')). To EQ (' good ')
expect (products_json[1][' description ')). To EQ (' just so ')

expect (products_json[0][' uri"). to End_with ('/PRODUCTS/1 ')
expect (products_json[1][' URI ']). To End_with ('/PRODUCTS/2 ')


In the APP/VIEWS/PRODUCTS/INDEX.JSON.RABL

Collection @products,: Object_root=>false
Attributes:id,: Name,:d escription

Node:uri do |product|
Product_url Product
End


4.get/products = user GET a product of specified ID

Step 1: Create the appropriate controller method. Return HTTP 200

Add Test: SPEC/PRODUCTS/PRODUCTS_CONTROLLER_SPEC.RB

It ' get product by Product ID ' does
Get:show, {: id = 1}
Expect (response). To Have_http_status (200)
End


Corresponding changes: APP/CONTROLLERS/PRODUCTS_CONTROLLER.RB

Def show
Render:nothing = True
End


Corresponding changes: CONFIG/ROUTES.RB

Resources:p Roducts Do
Collection do
Get:index
End

Member do
Get:show
End
End

Rake Spec Tested by


Step 2: Create the appropriate JSON display

Add Test: SPEC/PRODUCTS/PRODUCTS_CONTROLLER_SPEC.RB

Before (: All) do
#... ...
@product = Product.new ({: id = 1,: name = ' Apple juice ',:d escription = ' good '})
End

It ' get product by Product ID ' does
Expect (PRODUCT). To receive (: Find). With (1). And_return (@product). Once

Get:show, {: id = 1,: Format =: JSON}
Expect (response). To Have_http_status (200)

Product_json = Json.parse (response.body)
Expect (product_json[' id '). to EQ (1)
Expect (product_json[' name '). To EQ (' apple juice ')
Expect (product_json[' description '). To EQ (' good ')
Expect (product_json[' URI '). To End_with ('/PRODUCTS/1 ')
End


Corresponding changes: APP/CONTROLLERS/PRODUCTS_CONTROLLER.RB

Def show
@product = Product.find (params[:id].to_i)
End

Q:params[:id].to_i, why is this from the test code here Params[:id] it makes a string type?


Added JSON display: APP/VIEWS/PRODUCTS/SHOW.JSON.RABL

Object False

Node (: ID) {|product| @product. ID}
Node (: name) {|product| @product. Name}
Node (:d escription) {|product| @product. Description}
Node (: URI) {|product| Product_url @product}


Perform a test by


Step 3: Refactoring Rabl

Change App/views/products/show.json.rabl

Object @product

Attributes:id,: Name,:d escription

Node (: URI) {|product| Product_url product}


Change App/views/products/index.json.rabl

Collection @products

Extends ' products/show '


Configure RABL: Create file Config/initializers/rabl_config.rb

Rabl.configure do |config|
Config.include_json_root = False
End


Perform a test, pass, thus reducing the repeated code between the Rabl


Step 4:http 404

Add Test: SPEC/PRODUCTS/PRODUCTS_CONTROLLER_SPEC.RB

It ' get 404 when product not found ' do
Expect (PRODUCT). To receive (: Find). with (+). And_raise (Activerecord::recordnotfound)

Get:show, {: id = =,: Format =: JSON}
Expect (response). to Have_http_status (404)
End


Corresponding changes:

Class ProductsController < Applicationcontroller
Rescue_from Activerecord::recordnotfound, with::p Roduct_not_found

#... ...

Def show
@product = Product.find (Params[:id])
End

Protected
def Product_not_found
Response.Status = : Not_found
End
End

References Rescue_from


(In the update, Welcome to enlighten me)

The part that will be changed is how to test the RSpec, refer to: http://betterspecs.org/

Copyright notice: This article Bo Master original articles, blogs, without consent may not be reproduced.

Intentionally practicing--rails RESTful (i)

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.