Những điểm thay đổi và chức năng mới cần biết về Rails 5
This post hasn't been updated for 8 years
Source
今から知っておきたいRails 5の新機能・変更点 - ryohashimoto
Background
Anh chàng 1 năm trước còn ngồi hì hục code rails 8 tiếng mỗi ngày, 1 năm trở lại đây chuyển sang iOS và Android và không động tới 1 dòng code - I am Minh.
Gần đây tôi được tham gia lead 1 dự án rails và những kỉ niệm ngọt ngào 1 năm trước lại trở về quanh đây. Nhớ ngày ấy, những tin đồn về sự ra mắt của Rails 5, còn hì hục cãi nhau với khách hàng bảo không cần nâng cấp lên bản Rails 4 mới hơn đâu, cứ chờ 5 ra rồi làm một thể. Giờ thì trang web đó cũng không còn nữa, nhưng bản Rails 5 đáng trông đợi ngày nào cũng đã ra đời.
Thật tuyệt vời ^^!!!
Đầu tiên
Trước khi Ruby 2.3 ra mắt, bản beta của rails 5.0 đã chính thức được phát hành.
Cùng với việc Rails 5 sẽ có chức năng mới phục vụ cho WebSocket server cũng như JSON API server, đã có rất nhiều thay đổi lớn phía trong để có thể chạy trên phiên bản Ruby 2.2.2 trở lên. Ngoài ra, có rất nhiều các điểm thay đổi lớn được cho vào như model được kế thừa từ ApplicationRecord hay có thể chạy Rake task bằng rails command.
Ở bài viết này, tôi sẽ dựa trên lịch sử pull requests và issues của rails project trên gihub để giới thiệu về các điểm thay đổi cũng như chức năng mới của Rails 5.
Chức năng mới
Rails API
Thay vì ActionController::Base, bằng việc kế thừa ActionController::API ở controller đã giúp việc cấu trúc một Rails app nhẹ dành cho JSON API server thành công.
Trong trường hợp muốn tạo Rails app chỉ hoàn toàn cho API, hãy chỉ định option --api
với rails new
$ rails new my_api --api
Sau đó sẽ có những xử lý như sau được thực hiện ở phía bên trong
- Những middleware tối thiếu để có thể chạy API server sẽ được load.
- ApplicationController sẽ thừa kế ActionController::API
- Không thực hiện việc tạo view cũng như asset của generator.
Nếu muốn chuyển rails app đang có thành dạng chỉ có API không thôi hãy tham khảo bài dưới đây.
Rails API to Be Part of Rails 5
Action Cable
Bằng việc sử dụng Action Cable
sẽ giúp chúng ta thêm chức năng của WebSocket (truyền tin song phương realtime) vào Rails app một cách dễ dàng. Action Cable
có cả chức năng của server lẫn client.
Ở phía server sử dụng class ApplicationCable::Connection
và ApplicationCable::Channel
.. để implement, còn bên client dựa vào App.cable.subscriptions.create
của CoffeeScript(JavaScript)
để gọi method AppearanceChannel#subscribed
bên server.
Có thể tạo code của cả 2 bên server và client bằng generator. Dưới đây là ví dụ tạo channel tên là chat
.
$ rails generate channel chat
Hãy tham khảo tại đây để biết thêm chi tiết về sample code này.
Có thể chạy rake
task từ rails
command
Đã có thể thực hiện các loại task chạy bằng rake
command bằng rails
command.
Ví dụ, migrate DB có thể chạy bằng rails db:migrate
, hay việc confirm routing bằng rails routes
.
Implement rake proxy for rails cli
Turbolinks 5
Bằng việc gán data-turbolinks-permanent
vào DOM element sẽ giúp duy trì được giữa các trang và tránh được việc khởi tạo trạng thái lại và nâng cao được tốc độ.
Với những element cố định giữa các trang ví dụ như sidebar hãy gắn data-turbolinks-permanent
, những element không giữ qua các trang hãy gắn data-turbolinks-temporary
.
<div id="nav" data-turbolinks-permanent></div>
<div id="footer" data-turbolinks-temporary></div>
Support Sprockets 3
Cho tới bản Rails 4
cần chỉ định có precompile asset nào trong file config/initializers/assets.rb
, tuy nhiên tại Rails 5
thì có thể chỉ định tại file manifest.js
ở directory app/assets/config/
.
Ở trạng thái khởi tạo app thì file manifest.js
sẽ như dưới đây:
//= link_tree ../images
//= link_directory ../javascripts .js
//= link_directory ../stylesheets .css
(Tại trang tham khảo dưới đây đang là Sprockets 4
, tuy nhiên hiện nay vẫn đang chỉ là Sprockets 3
mà thôi)
Rails 5: The Sprockets 4 Manifest
ActiveRecord::Attributes
Bằng việc chỉ định thuộc tính tại attribute của model, chúng ta có thể customize phương thức lấy thuộc tính của model bằng SQL hay truyền vào method where
của ActiveRecord::Relation
.
Với ví dụ dưới đây, bằng việc chỉ định integer với attribute có thuộc tính được định nghĩa là decimal
trong DB
create_table :store_listings, force: true do |t|
t.decimal :price_in_cents
end
chúng ta có thể convert được về dạng số nguyên.
class StoreListing < ActiveRecord::Base
attribute :price_in_cents, :integer
end
Có sự khác biệt như dưới đây với trước và sau khi convert bằng attribute
.
# before
store_listing.price_in_cents
=> BigDecimal.new(10.1)
# after
store_listing.price_in_cents
=> 10
Chi tiết hãy tham khảo link dưới đây.
ActiveRecord::Attributes::ClassMethods
Thêm các method liên quan tới query (#or, #left_outer_joins, #left_joins)
Method #left_outer_joins
thực hiện kết hợp ngoài và #or
có thể chỉ định điều kiện OR bằng SQL đã được thêm vào ActiveRecord::Relation
.
Post.where('id = 1').or(Post.where('id = 2'))
=> SELECT * FROM posts WHERE (id = 1) OR (id = 2)
User.left_outer_joins(:posts)
=> SELECT "users".* FROM "users" LEFT OUTER JOIN "posts" ON "posts"."user_id" = "users"."id"
Ngoài ra, alias #left_joins
của #left_outer_joins
cũng được thêm vào.
Added #or to ActiveRecord::Relation
added ActiveRecord::Relation#outer_joins
Thêm #pluck và #without vào module Enumerable
Đã có thể sử dụng hoạt động giống với method #pluck
(chuyển column của record nhất định sang array) đối với hash array.
[{ name: "David" }, { name: "Rafael" }, { name: "Aaron" }].pluck(:name)
=> ["David", "Rafael", "Aaron"]
Thêm nữa, method #without
loại bỏ element nhất định trong array cũng đã được thêm vào.
people = ["David", "Rafael", "Aaron", "Todd"]
people.without "Aaron", "Todd"
=> ["David", "Rafael"]
Thêm option touch
vào #save
của ActiveRecord
Khi lưu record, nếu truyền touch: false
vào option của method #save
sẽ giúp chúng ta không làm thay đổi timestamp.
Tại ví dụ dưới đây, sau khi thay đổi data của model object article
, giá trị updated_at
không bị thay đổi.
updated_at = article
artile.save!(touch: false)
article.update_at == updated_at
=> true
Provide :touch option to save() to accommodate saving without updating timestamps
Thêm method ActiveRecord::Relation#in_batches
ActiveRecord#find_in_batches
(thực hiện xử lý đối với model có số lượng data rất lớn) truyền array vào block hay truyền record, thì method ActiveRecord#in_bathces
có thể truyền ActiveRecord::Relation
vào block. Nếu truyền of
vào option thì có thể thay đổi batch size.(default: 1000)
Person.in_batches.each_record(&:party_all_night!)
Person.in_batches.update_all(awesome: true)
Person.in_batches.delete_all
Person.in_batches.each do |relation|
relation.delete_all
sleep 10 # Throttles the delete queries
end
Điểm thay đổi
Nếu nơi tham chiếu của belongs_to
mà nil sẽ sinh validation error
Để back về hoạt động như trước bản Rails 4, cần chỉ định optional: true
tại belongs_to
option.
belongs_to should default to required: true
Model ActiveRecord
kế thừa ApplicationRecord
Tại bản Rails 5, nếu đã tạo app mới thì file app/models/application_record.rb
sẽ được tạo ra như dưới đây và khi tạo model khác nữa thì sẽ không phải kế thừa từ ActiveRecord::Base
mà từ ApplicationRecord
class ApplicationRecord < ActiveRecord::Base
self.abstract_class = true
end
Từ trước tới nay, nếu muốn thêm chức năng vào toàn thể model của app thì cần thực hiện monkeypatch vào ActiveRecord::Base
hoặc cần include
module, tuy nhiên từ Rails 5
chỉ cần thêm method và ApplicationRecord
là ok.
Introduce ApplicationRecord, an Active Record layer supertype
Job của ActiveJob cũng kế thừa ApplicationJob
ActiveJob cũng giống vậy, các job không phải kế thừa ActiveJob::Base
nữa mà sẽ thực hiện kế thừa ApplicationJob
ở file app/jobs/application_job.rb
.
class ApplicationJob < ActiveJob::Base
end
Add explicit base class for ActiveJob jobs
ActionController::Parameters
khong kế thừa hash nữa
Từ trước tới nay Parameters
kế thừa ActiveSupport::HashWithIndifferentAccess
, do có mối nguy hiểm rằng có thể tương tác với các parameter chưa được cấp phép tại các method của module Enumerable
nên đã có một số thay đổi. (Nếu đang sử dụng method hash.. sẵn có, cần chú ý khi upgrade)
Make AC::Parameters not inherited from Hash
Bỏ khuyến khích sử dụng alias_method_chain
Rails 5 sử dụng Ruby 2.2.2 trở lên cho nên thay vì alias_method_chain
của ActiveSupport
, sử dụng Module #prepend của Ruby.
Rails 5, Module#prepend, and the End of alias_method_chain
Tổng kết
Rails 5 đã mở rộng tầm của app với Rails API và Action Cable.., ngoài ra đã gãi đúng chỗ ngứa với việc thêm các method query thuận tiện. Hiện nay đã có phiên bản beta với Rails 5, cho nên các bạn có thể thử nghiệm chức năng mới hay thử upgrade từ phiên bản 4 lên xem thử. Tiến lên !!!
Trang tham khảo
Rails 5.0.0.beta1: Action Cable, API mode, Rails command
This week in Rails: Rails 5 - The Beta Awakens
Cảm ơn các bạn đã xem bài.
All Rights Reserved