Ruby_Create application with scaffold
Trong bài này, mình sẽ tạo một ứng dụng nhỏ để tìm hiểu về các tính năng mạnh mẽ của Rails. Sử dụng script scaffold generator tự động sinh ra phần lớn chức năng để nhanh chóng tạo app, dựa vào đó để học về tổng quan của Web và Rails programming nâng cao. Lập kế hoạch Các bước thực hiện bên dưới ...
Trong bài này, mình sẽ tạo một ứng dụng nhỏ để tìm hiểu về các tính năng mạnh mẽ của Rails. Sử dụng script scaffold generator tự động sinh ra phần lớn chức năng để nhanh chóng tạo app, dựa vào đó để học về tổng quan của Web và Rails programming nâng cao.
Lập kế hoạch
Các bước thực hiện bên dưới đã được giải thích ở bài trước nên có thể refer lại.
- Trước tiên, chúng ta hãy lên kế hoach để thực hiện tạo ứng dụng. Ta bắt đầu từ việc tạo khung của app bằng lệnh rails new.
$ cd ~/workspace $ rails _5.1.2_ new toy_app
- Tiếp theo, Edit Gemfile
source 'https://rubygems.org' gem 'rails', '5.1.2' gem 'puma', '3.9.1' gem 'sass-rails', '5.0.6' gem 'uglifier', '3.2.0' gem 'coffee-rails', '4.2.2' gem 'jquery-rails', '4.3.1' gem 'turbolinks', '5.0.1' gem 'jbuilder', '2.7.0' group :development, :test do gem 'sqlite3', '1.3.13' gem 'byebug', '9.0.6', platform: :mri end group :development do gem 'web-console', '3.5.1' gem 'listen', '3.0.8' gem 'spring', '2.0.2' gem 'spring-watcher-listen', '2.0.1' end group :production do gem 'pg', '0.20.0' end # Windows does not include zoneinfo files, so bundle the tzinfo-data gem gem 'tzinfo-data', platforms: [:mingw, :mswin, :x64_mingw, :jruby]
- Install gem ở local (bỏ qua gem dùng cho môi trường product bằng việc add thêm option --without production)
$ bundle install --without production
- Quản lý version Toy app trên Git
$ git init Reinitialized existing Git repository in /home/ubuntu/workspace/toy_app/.git/ $ git add -A $ git commit -m "Initialize repository"
- Tạo repo trên Bitbucket rồi push file đã tạo lên remote repository này
$ cd /home/ubuntu/workspace/toy_app/.git/ $ git remote add origin git@bitbucket.org:tranthitinh/toy_app.git $ git push -u origin master
- Chuẩn bị cho việc deploy. (Hiển thị Hello, world) Add action vào Application controller app/controllers/application_controller.rb
class ApplicationController < ActionController::Base protect_from_forgery with: :exception def hello render html: "hello, world!" end end
Setting root rooting config/routes.rb
Rails.application.routes.draw do root 'application#hello' end
Push lên heroku
$ git commit -am "Add hello" $ heroku create Creating app... done, ⬢ vast-lake-37431 https://vast-lake-37431.herokuapp.com/ | https://git.heroku.com/vast-lake-37431.git $ git push heroku master
Đến đây, bạn đã chuẩn bị xong để tạo bên trong app. Khi tạo Web app, thường thì đầu tiên sẽ tạo data model để mô tả cấu trúc của app. Trong Toy app lần này sẽ tạo micro blog chỉ support user và micro post ngắn. Trước tiên thì tạo user model, tiếp theo là tạo micro post model.
Thiết kế model của user
Có rất nhiều phương pháp đăng ký user trên Web nhưng ở đây mình chỉ sử dụng những cái tối thiểu như bên dưới. (id là unique)
users | |
---|---|
id | integer |
name | string |
istring |
users tương ưng là table của database. Các thuộc tính id, name, email tương ứng là các columns trong table.
Thiết kế model của micro post
Cũng như user, tạo model của micro post đơn giản như bên dưới
microposts | |
---|---|
id | integer |
content | text |
user_id | string |
Users resource
Ở đây sẽ implement users data model để hiển thị model đó theo Web interface. Data model này và Web interface được tổ hợp thành Users resource, Users có thể được coi là các đối tượng có thể tự do create/ get/ update/ delete thông qua giao thức HTTP. Như đã giới thiệu từ đầu, Users reource này thì toàn bộ sẽ được tạo ra bằng scaffold generator. Scaffold của Rails thì được tạo thông qua lệnh scaffold trong rails generate script. Tham số của lệnh saffold thì dùng tên resource (ở đây là User), add thêm parameter lựa chọn thuộc tính của data model (ở đây là add thêm option name:string và email:string, Vì id được tự động add vào database với vai trò là Primary key nên ở đây không cần add)
$ rails generate scaffold User name:string email:string Running via Spring preloader in process 4116 invoke active_record create db/migrate/20171102064247_create_users.rb create app/models/user.rb invoke test_unit create test/models/user_test.rb create test/fixtures/users.yml invoke resource_route route resources :users invoke scaffold_controller create app/controllers/users_controller.rb invoke erb create app/views/users create app/views/users/index.html.erb create app/views/users/edit.html.erb create app/views/users/show.html.erb create app/views/users/new.html.erb create app/views/users/_form.html.erb invoke test_unit create test/controllers/users_controller_test.rb invoke helper create app/helpers/users_helper.rb invoke test_unit invoke jbuilder create app/views/users/index.json.jbuilder create app/views/users/show.json.jbuilder create app/views/users/_user.json.jbuilder invoke test_unit create test/system/users_test.rb invoke assets invoke coffee create app/assets/javascripts/users.coffee invoke scss create app/assets/stylesheets/users.scss invoke scss create app/assets/stylesheets/scaffolds.scss
Tiếp theo, cần migrate database bằng lệnh rails db:migrate.
$ rails db:migrate == 20171102064247 CreateUsers: migrating ====================================== -- create_table(:users) -> 0.0010s == 20171102064247 CreateUsers: migrated (0.0011s) =============================
※Ở Rails version <5 thì lệnh db:migrate không phải lệnh rails mà sử dụng lệnh rake. Cần phải định nghĩa version của lệnh rake trong Gemfile nên cần chạy lệnh bundler exec.
$ bundle exec rake db:migrate
Tiếp theo, khởi động Web server của môi trường local bằng lệnh rails server
$ rails server -b $IP -p $PORT
Confirm trang user
Khi mở root URL「/」trên trình duyệt thì sẽ hiển thị page「hello, world!」nhưng vì tạo ra Users resource bằng scaffold nên có nhiều trang quản lý user được thêm vào.
URL | Action | Sử dụng |
---|---|---|
/users | index | Page list hết toàn bộ user |
/users/1 | show | Page hiển thị user có id=1 |
/users/new | new | Page tạo user mới |
/users/1/edit | edit | Page edit user có id=1 |
Màn hình tạo mới user: Thử nhập tên và địa chỉ email vào rồi nhấn nút [Create User] Danh sách toàn bộ user Màn hình xem thông tin user Màn hình Edit thông tin user Xóa user bằng cách nhấn Detroy của user tương ứng.
Hoạt động của mô hình MVC
Ở đây mình sẽ tìm hiểu về tham chiếu resource của mô hình MVC(Model-View-Controller). Ví dụ xử lý bên trong mô hình MVC khi có action mở trang index trên trình duyệt.
- Từ trình duyệt gửi request của URL「/users」lên Rails server
- 「/users」request được gán cho index action trong Users controller nhờ cơ chế routing của Rails.
- Thực hiện index action, từ đó gửi yêu cầu get toàn bộ user (User.all) đến User model.
- User model tiếp nhận yêu cầu, get toàn bộ user từ database.
- Từ User model trả về cho controller danh sách toàn bộ user đã get được từ database.
- Users controller lưu danh sách user vào biến @users rồi chuyển qua index view.
- index view khởi động, chạy ERB (Embedded RuBy) tạo (rendering) HTML.
- controller tiếp nhận HTML đã tạo ở view rồi trả về cho trình duyệt.
Nhược điểm của Users resource
Users resource đã tạo ra bằng scaffold thì giúp bạn nhanh chóng nắm được overview của Rails nhưng nó cũng bao gồm những nhược điểm bên dưới:
- Không xác minh data. Ở đây, có thể để trống user name, input mail address bừa bãi cũng được.
- Không xác thực data. Không login/logout nên bất kỳ ai cũng có thể thao tác.
- Không viết test.
- Layout và style không được điều chỉnh đẹp.
- Code khó hiểu.
Microposts resource
Tương tự như Users reource, bây giờ chúng ta sẽ tạo microposts resource.
$ rails generate scaffold Micropost content:text user_id:integer Running via Spring preloader in process 1725 invoke active_record create db/migrate/20171113021918_create_microposts.rb create app/models/micropost.rb invoke test_unit create test/models/micropost_test.rb create test/fixtures/microposts.yml invoke resource_route route resources :microposts invoke scaffold_controller create app/controllers/microposts_controller.rb invoke erb create app/views/microposts create app/views/microposts/index.html.erb create app/views/microposts/edit.html.erb create app/views/microposts/show.html.erb create app/views/microposts/new.html.erb create app/views/microposts/_form.html.erb invoke test_unit create test/controllers/microposts_controller_test.rb invoke helper create app/helpers/microposts_helper.rb invoke test_unit invoke jbuilder create app/views/microposts/index.json.jbuilder create app/views/microposts/show.json.jbuilder create app/views/microposts/_micropost.json.jbuilder invoke test_unit create test/system/microposts_test.rb invoke assets invoke coffee create app/assets/javascripts/microposts.coffee invoke scss create app/assets/stylesheets/microposts.scss invoke scss identical app/assets/stylesheets/scaffolds.scss
Chạy lệnh migrate
$ rails db:migrate == 20171113021918 CreateMicroposts: migrating ================================= -- create_table(:microposts) -> 0.0019s == 20171113021918 CreateMicroposts: migrated (0.0030s) ========================
Confirm trang Micropost
URL | Action | Sử dụng |
---|---|---|
/microposts | index | Page list hết toàn bộ microposts |
/microposts/1 | show | Page hiển thị microposts có id=1 |
/microposts/new | new | Page tạo microposts mới |
/microposts/1/edit | edit | Page edit microposts có id=1 |
/microposts/1 | update | Action update microposts có id=1 |
/microposts/1 | destroy | Xóa microposts có id=1 |
Validation
Ví dụ giới hạn max length của content là 140 ký tự. app/models/micropost.rb
class Micropost < ApplicationRecord validates :content, length: { maximum: 140 } end
Quan hệ 1-n, 1-1
Một user có nhiều bài post app/models/user.rb
class User < ApplicationRecord has_many :microposts end
1 bài post thuộc 1 user app/models/micropost.rb
class Micropost < ApplicationRecord belongs_to :user validates :content, length: { maximum: 140 } end
Trong bảng microposts đã tạo cột user_id nên dựa vào đó Rails và Active Record đã có thể tạo quan hệ giữa micropost và user.
Deploy app
Đăng ký trên Bitbucket
$ git status $ git add -A $ git commit -m "Finish toy app" $ git push
Deploy trên heroku
$ git push heroku $ heroku run rails db:migrate