Có gì mới trong Rails 5.1?

Vài ngày trước, bản beta đầu tiên của Rails 5.1 đã được phát hành. Trong bài viết này, mình xin giới thiệu sơ qua về một số tính năng mới trong Rails 5.1.

Hỗ trợ Yarn

Rails 5.1 sẽ cho phép quản lý các dependency của Javascript từ NPM thông qua Yarn. Điều này sẽ giúp việc sử dụng các thư viện như React, VueJS hay bât kỳ mọt thư viện nào khác từ NPM trở nên dễ dàng hơn. Việc hỗ trợ Yarn được tích hợp với cơ chế pipeline, vì thế các dependency sẽ làm việc liên tục trong ứng dụng Rails 5.1.

Hỗ trợ tùy chọn Webpack

Gem webpacker chính thức của Rails đã được tích hợp dễ dàng hơn trong app Rails. Sử dụng tùy chọn --webpack khi tạo application mới để cài đặt Webpack cho app.

# For new projects
rails new foobar --webpack=react

# in existing projects
rails webpacker:install:react

Goodbye, jquery

Rails Ú không còn phụ thuộc vào jQuery, vì thế jquery-rails sẽ không còn là mặc định. Bạn có thể vẫn còn phải sử dụng jQuery, khi đó bạn cần phải thêm nó thông qua Yarn:

bin/yarn add jquery

System test với Capybara

Rails 5.1 được trang bị ActionDispatch::IntegrationTest cho phép bạn sử dụng Capybara trong kiểm thử tích hợp mà không cần phải thêm bất kỳ cấu hình nào. Mặc định là trình duyệt Chrome sẽ chạy kiểm thử nhưng ta có thể cấu hình cho các trình duyệt Poltergeist, Selenium hay Firefox thực hiện. Dưới đây là một ví dụ trích từ Rails docs:

require 'application_system_test_case'

class Users::CreateTest < ApplicationSystemTestCase
  test "adding a new user" do
    visit users_path
    click_on 'New User'

    fill_in 'Name', with: 'Arya'
    click_on 'Create User'

    assert_text 'Arya'
  end
end

Encrypted secrets

Rails 5.1 sẽ cho phép quản lý application secrets như mật khẩu hay secret tokensheo một cách an toàn. Chạy bin/rails secrets:setup để thiết lập một file encrypted secrets mới. Nó sẽ sinh ra một master key được lưu bên ngoài repository. Seccrets sẽ được giải mã trong production, sử dụng một khóa được lưu trong biến môi trường RAILS_MASTER_KEY hoặc trong một file khóa.

Hợp nhất form_for và form_tag thành form_with

Trước Rails 5.1, có 2 interfaces xử lý HTML form là form_for cho các model và form_tag cho các URL. Rails 5.1 sẽ hợp nhất 2 interfaces trên thành form_with có thể sinh form tags dựa trên các URL, scope hay model.

# Using just a URL:
 
<%= form_with url: posts_path do |form| %>
  <%= form.text_field :title %>
<% end %>
 
# =>
<form action="/posts" method="post" data-remote="true">
  <input type="text" name="title">
</form>
 
# Adding a scope prefixes the input field names:
 
<%= form_with scope: :post, url: posts_path do |form| %>
  <%= form.text_field :title %>
<% end %>
# =>
<form action="/posts" method="post" data-remote="true">
  <input type="text" name="post[title]">
</form>
 
# Using a model infers both the URL and scope:
 
<%= form_with model: Post.new do |form| %>
  <%= form.text_field :title %>
<% end %>
# =>
<form action="/posts" method="post" data-remote="true">
  <input type="text" name="post[title]">
</form>
 
# An existing model makes an update form and fills out field values:
 
<%= form_with model: Post.first do |form| %>
  <%= form.text_field :title %>
<% end %>
# =>
<form action="/posts/1" method="post" data-remote="true">
  <input type="hidden" name="_method" value="patch">
  <input type="text" name="post[title]" value="<the title of the post>">
</form>

Parameterized mailers

Cho phép tất cả các phương thức trong mailer class sử dụng các param chỉ định thông thường để chia sẻ các biến đối tượng, header và các thiết lập thông thường khác.

class InvitationsMailer < ApplicationMailer
 
  before_action { @inviter, @invitee = params[:inviter], params[:invitee] }
  before_action { @account = params[:inviter].account }
 
  def account_invitation
    mail subject: "#{@inviter.name} invited you to their Basecamp (#{@account.name})"
  end
 
  def project_invitation
    @project    = params[:project]
    @summarizer = ProjectInvitationSummarizer.new(@project.bucket)
 
    mail subject: "#{@inviter.name.familiar} added you to a project in Basecamp (#{@account.name})"
  end
end
 
InvitationsMailer.with(inviter: person_a, invitee: person_b).account_invitation.deliver_later

Xem thêm: ActionMailer::Parameterized docs

Direct & resolved routes

Rails 5.1 thêm 2 phương thức resolvedirect cho routing DSL. Phương thức resolve cho phép điều chỉnh các ánh xạ polymorphic trong các model:

resource :basket
resolve("Basket") { [:basket] }
<%= form_for @basket do |form| %>
  <!-- basket form -->
<% end %>

Nó sẽ sinh ra URL /basket thay cho /baskets/:id. Phương thức direct cho phép tạo các custom URL helper.

direct(:homepage) { "http://www.rubyonrails.org" }
>> homepage_url
=> "http://www.rubyonrails.org"

Giá trị trả về của block phải là một tham số hợp lệ cho phương thức url_for.

direct :commentable do |model|
  [ model, anchor: model.dom_id ]
end

direct :main do
  { controller: 'pages', action: 'index', subdomain: 'www' }
end

Updating...

Source: Bài viết tham khảo từ các nguồn:

http://edgeguides.rubyonrails.org/5_1_release_notes.html http://nithinbekal.com/posts/rails-5.1-features/