0
0
Lập trình
Admin Team
Admin Teamtechmely

Cách Sử Dụng Scope của Rails View Helper với Tùy Chọn include_all_helpers

Đăng vào 6 tháng trước

• 5 phút đọc

Chủ đề:

#rails#ruby

Giới Thiệu

Trong bài viết này, chúng ta sẽ tìm hiểu về scope của các phương thức được định nghĩa trong Rails view helpers, cách thay đổi scope này và quy trình từng bước để thay đổi an toàn scope trong một ứng dụng hiện có.

Phương Thức Được Định Nghĩa Trong Helpers Có Thể Gọi Từ Bất Kỳ View Nào

Ví dụ, giả sử bạn có phương thức UsersHelper#display_name được định nghĩa như sau:

ruby Copy
# app/helpers/users_helper.rb
module UsersHelper
  def display_name(user)
    "#{user.lastname} #{user.firstname}"
  end
end

Phương thức này có thể được sử dụng không chỉ trong các view được render bởi UsersController, mà còn trong các view được render bởi các controller khác:

ruby Copy
# app/controllers/posts_controller.rb
class PostsController
  def index
    @posts = Post.all
  end
end
erb Copy
<% # app/views/posts/index.html.erb %>
<% @posts.each do |post| %>
  <p><%= post.content %></p>
  <small><%= display_name(post.user) %></small> <!-- display_name có thể sử dụng -->
<% end %>

Nói cách khác, các phương thức được định nghĩa trong view helpers có thể được sử dụng trong bất kỳ view nào. Tuy nhiên, với phạm vi rộng lớn như vậy, có một số mối quan tâm:

  • Để xác nhận rằng một phương thức helper không được sử dụng, bạn phải kiểm tra toàn bộ ứng dụng.
  • Khó khăn trong việc dự đoán hành vi khi có nhiều phương thức cùng tên được định nghĩa trong các helpers khác nhau.

Rails cung cấp một tùy chọn để giải quyết những mối quan tâm này.

Tùy Chọn config.action_controller.include_all_helpers

Như đã đề cập ở trên, theo mặc định, các controller trong Rails sẽ tải tất cả các helpers. Hành vi này phụ thuộc vào thiết lập của config.action_controller.include_all_helpers.

Cấu hình xem tất cả các view helpers có sẵn ở mọi nơi hay chỉ được giới hạn trong controller tương ứng.

Giá trị mặc định là true.

Vì vậy, nếu bạn thiết lập tùy chọn này trong config/application.rb, hành vi sẽ thay đổi:

ruby Copy
module Example
  class Application < Rails::Application # Khởi tạo cấu hình mặc định cho phiên bản Rails được tạo ra ban đầu.
    config.load_defaults 8.0
    config.action_controller.include_all_helpers = false
  end
end

Với thiết lập này, một phương thức như display_name định nghĩa trong UsersHelper sẽ không thể được gọi từ một view được render bởi PostsController:

ruby Copy
<% # app/views/posts/index.html.erb %>
<% @posts.each do |post| %>
  <p><%= post.content %></p>
  <!-- Không thể gọi! -->
  <small><%= display_name(post.user) %></small> <!-- phương thức 'display_name' không xác định cho ... -->
<% end %>

Làm Thế Nào Để Xác Định Helper Được Áp Dụng?

Giả sử chúng ta có cấu trúc kế thừa controller và helper như sau:

plaintext Copy
app/
├── controllers
│ ├── admin
│ │ ├── application_controller.rb
│ │ └── users_controller.rb
│ ├── application_controller.rb
│ ├── posts_controller.rb
│ └── users_controller.rb
└── helpers
├── admin
│ ├── application_helper.rb
│ └── users_helper.rb
├── application_helper.rb
├── posts_helper.rb
└── users_helper.rb

Trong bối cảnh của UsersController, các helpers được bao gồm là:

  1. UsersHelper
  2. ApplicationHelper (luôn luôn)

Điều này phụ thuộc vào kế thừa controller. UsersController tự động bao gồm UsersHelper, và ApplicationController bao gồm ApplicationHelper. Do đó, UsersController có cả phương thức từ UsersHelperApplicationHelper.

Di Chuyển Một Ứng Dụng Hiện Có Sang include_all_helpers = false

Thiết lập này rất hữu ích. Dưới đây là lộ trình di chuyển cho các ứng dụng hiện có.

Bước Đầu Tiên

Bước đầu tiên là, tất nhiên, thiết lập config.action_controller.include_all_helpers = false:

ruby Copy
module Example
  class Application < Rails::Application
    config.load_defaults 8.0
    config.action_controller.include_all_helpers = false
  end
end

Chỉ với thiết lập này, bạn sẽ gặp lỗi ở những nơi mà các phương thức helper "tình cờ có sẵn". Như một biện pháp tạm thời, bao gồm tất cả các helpers trong ApplicationHelper để duy trì hành vi hiện tại:

ruby Copy
# app/helpers/application_helper.rb
module ApplicationHelper
  include Admin::ApplicationHelper
  include Admin::UsersHelper
  include PostsHelper
  include UsersHelper
end

Giảm Dần Sự Phụ Thuộc

Từ đây, hãy giảm dần sự phụ thuộc từng bước. Ví dụ, nếu mọi thứ dưới Admin::* đều kế thừa từ Admin::ApplicationController, hãy nhóm chúng lại:

ruby Copy
# app/helpers/admin/application_helper.rb
module Admin::ApplicationHelper
  include Admin::UsersHelper
end

Sau đó, loại bỏ các helpers khỏi ApplicationHelper nếu chúng chỉ được sử dụng trong một controller cụ thể:

ruby Copy
module ApplicationHelper
  include Admin::ApplicationHelper
  include UsersHelper
end

Khi Các Phương Thức Helper Từ Gems Dừng Hoạt Động

Điều này có thể xảy ra với các gems như font-awesome-rails. Gem này cung cấp phương thức helper view fa_icon. Nhưng khi config.action_controller.include_all_helpers = false, bạn phải bao gồm nó một cách rõ ràng:

ruby Copy
# app/helpers/application_helper.rb
module ApplicationHelper
  include FontAwesome::Rails::IconHelper
end

Tóm Tắt

  • Theo mặc định, các phương thức được định nghĩa trong view helpers có thể được gọi từ bất kỳ view nào của controller.
  • Thiết lập config.action_controller.include_all_helpers = false hạn chế các helpers được tải về chỉ cho những helpers tương ứng với controller đó (và chuỗi kế thừa của nó).
  • ApplicationHelper luôn được bao gồm bất kể thiết lập nào, làm cho nó trở thành nơi lý tưởng để đặt các phương thức chung.
  • Để di chuyển, lộ trình an toàn là: “thu thập tất cả vào ApplicationHelper trước → sau đó từ từ di chuyển và giảm bớt.”

Những Lưu Ý Quan Trọng

  • Khi thay đổi cấu hình, hãy đảm bảo kiểm tra lại tất cả các view để tránh lỗi.
  • Nên sử dụng các phương thức helper một cách rõ ràng và cụ thể cho từng controller để tăng tính bảo trì.

Câu Hỏi Thường Gặp (FAQ)

  1. Tại sao phải sử dụng include_all_helpers = false?

    • Việc này giúp quản lý và kiểm soát tốt hơn các phương thức helper, tránh xung đột và lỗi không rõ nguyên nhân.
  2. Có cách nào để sử dụng lại các phương thức helper đã bị loại bỏ không?

    • Bạn có thể bao gồm lại các phương thức cần thiết trong ApplicationHelper hoặc các helper cụ thể của controller.
  3. Có ảnh hưởng gì đến hiệu suất không?

    • Việc giảm tải không cần thiết sẽ giúp cải thiện hiệu suất ứng dụng, nhất là trong các ứng dụng lớn.

Hy vọng bài viết này sẽ giúp bạn hiểu rõ hơn về việc sử dụng scope của Rails view helpers và cách tối ưu hóa ứng dụng của bạn!

Gợi ý câu hỏi phỏng vấn
Không có dữ liệu

Không có dữ liệu

Bài viết được đề xuất
Bài viết cùng tác giả

Bình luận

Chưa có bình luận nào

Chưa có bình luận nào