12/08/2018, 16:50

Tùy chỉnh lệnh rails generate để giới hạn số lượng file/thư mục được tạo ra

Khi bắt đầu làm quen với framework Ruby on Rails, thường thì chúng ta sẽ được hướng dẫn cách sử dụng generator thông qua lệnh generate. Đây là một công cụ đặc trưng và hữu ích được phát triển cho framework này, giúp cải thiện hiệu suất và workflow của bạn. Nó hỗ trợ lập trình viên Ruby on Rails ...

Khi bắt đầu làm quen với framework Ruby on Rails, thường thì chúng ta sẽ được hướng dẫn cách sử dụng generator thông qua lệnh generate. Đây là một công cụ đặc trưng và hữu ích được phát triển cho framework này, giúp cải thiện hiệu suất và workflow của bạn. Nó hỗ trợ lập trình viên Ruby on Rails nhanh chóng tạo ra những cấu trúc thư mục và file cần thiết cho một ứng dụng web theo mô hình MVC. Sau chưa đầy 2 phút, bạn đã có thể tạo ra một trang web tin tức nho nhỏ với các chức năng thêm, sửa, xóa một bài viết, hiển thị một hay tất cả các bài viết.

Có nhiều tham số đi kèm với lệnh generate của Rails, ví dụ như controller, model, scaffold, channel, task... Dưới đây, chúng ta sẽ nói đến 2 tham số phổ biến là controller và model.

Khi thực hiện câu lệnh này kèm theo tên controller mong muốn, có thể tạm gọi là có 5 loại file/thư mục được sinh ra: controller, view, helper, assets, controller test. Việc đọc nội dung hiển thị ở terminal khi thực thi câu lệnh cũng giúp chúng ta quan sát được điều này:

➜  demo-app git:(rails-generate) rails g controller user
Running via Spring preloader in process 4487
      create  app/controllers/user_controller.rb
      invoke  erb
      create    app/views/user
      invoke  test_unit
      create    test/controllers/user_controller_test.rb
      invoke  helper
      create    app/helpers/user_helper.rb
      invoke    test_unit
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/user.coffee
      invoke    scss
      create      app/assets/stylesheets/user.scss

Đôi khi, chúng ta không cần nhiều file/thư mục sinh ra như vậy. Ví dụ như bạn chỉ cần các file view và controller thôi, sự xuất hiện của những file khác sẽ là "thừa thãi", "không cần thiết" trong những tình huống như vậy. Khi này, cách đơn giản để giải quyết vấn đề là...xóa bằng tay những file khác kia đi. Tuy nhiên, cách này rõ ràng là bất tiện. Có một giải pháp khác hiệu quả và "cool ngầu" hơn, ấy là bạn cần bổ sung thêm các tham số cần thiết cho lệnh generate.

1.1. --no-assets

Với tham số --no-assets, sẽ không có các file js và css được tạo ra:

➜  demo-app git:(rails-generate) rails g controller user --no-assets
Running via Spring preloader in process 4697
      create  app/controllers/user_controller.rb
      invoke  erb
      create    app/views/user
      invoke  test_unit
      create    test/controllers/user_controller_test.rb
      invoke  helper
      create    app/helpers/user_helper.rb
      invoke    test_unit

Nếu như bạn chỉ muốn tạo ra file js hoặc css thì có thể thay --no-assets bằng tham số --no-stylesheets hoặc --no-javascripts tương ứng.

1.2. --no-helper

Để không tạo ra file helper, chúng ta có thể truyền vào tham số --no-helper cho lệnh generate. Khi kết hợp với cả tham số --no-assets vừa được giới thiệu, kết quả hiện thị ở terminal khá gọn gàng, cho thấy cấu trúc file/thư mục được sinh ra không bao gồm các file assets và helper:

➜  demo-app git:(rails-generate) rails g controller user --no-helper --no-assets
Running via Spring preloader in process 4890
      create  app/controllers/user_controller.rb
      invoke  erb
      create    app/views/user
      invoke  test_unit
      create    test/controllers/user_controller_test.rb

1.3. --no-template-engine

Thế còn với những file ở thư mục views thì sao, làm thế nào để không sinh ra các file này? Bạn có thể thực hiện lệnh generate kết hợp với tham số --no-template-engine:

➜  demo-app git:(rails-generate) rails g controller user --no-template-engine
Running via Spring preloader in process 4964
      create  app/controllers/user_controller.rb
      invoke  test_unit
      create    test/controllers/user_controller_test.rb
      invoke  helper
      create    app/helpers/user_helper.rb
      invoke    test_unit
      invoke  assets
      invoke    coffee
      create      app/assets/javascripts/user.coffee
      invoke    scss
      create      app/assets/stylesheets/user.scss

1.4. --no-test-framework

Chúng ta đã đề cập đến việc bỏ qua 3/5 loại file/thư mục khi thực hiện lệnh generate cho controller. Đối với file/thư mục test controller, tham số phù hợp cần truyền vào câu lệnh là --no-test-framework. Sử dụng kết hợp với các tham số đã nói đến ở trên, kết quả tạo ra thật ngắn gọn:

➜  demo-app git:(rails-generate) rails g controller user --no-test-framework --no-assets --no-helper --no-template-engine
Running via Spring preloader in process 5218
      create  app/controllers/user_controller.rb

Đối với câu lệnh này dùng để tạo ra cấu trúc file model và những thứ có liên quan, khi thực hiện nó thì mình tạm chia ra thành 3 loại file/thư mục được sinh ra: model, migration, test model. Các bạn có thể quan sát điều này ở terminal:

➜  demo-app git:(rails-generate) rails g model user name:string age:integer
Running via Spring preloader in process 5330
      invoke  active_record
      create    db/migrate/20180121235604_create_users.rb
      create    app/models/user.rb
      invoke    test_unit
      create      test/models/user_test.rb
      create      test/fixtures/users.yml

Tương tự như khi làm việc với controller, bạn có thể truyền tham số --no-test-framework để rails generator bỏ qua, không tạo các file/thư mục test khi khởi tạo model:

➜  demo-app git:(rails-generate) rails g model user name:string age:integer --no-test-framework
Running via Spring preloader in process 5462
      invoke  active_record
      create    db/migrate/20180121235958_create_users.rb
      create    app/models/user.rb

2.1. --no-migration

Nếu sử dụng tham số --no-migration kết hợp với --no-test-framework, chỉ có file model được tạo ra:

➜  demo-app git:(rails-generate) rails g model user name:string age:integer --no-migration --no-test-framework
Running via Spring preloader in process 5575
      invoke  active_record
      create    app/models/user.rb

Trước khi chuyển qua phần tiếp theo, các bạn có thể lưu ý rằng trong những tham số truyền vào lệnh generate đã được đề cập đến, bạn có thể thay "no" bằng "skip", ví dụ như: --skip-assets, --skip-test-framework...

Thay vì phải chỉ định thủ công các tham số tương ứng mỗi lần thực hiện lệnh generate, một cách khác nhanh chóng và ngắn gọn hơn nữa ấy là bạn có thể cấu hình trực tiếp trong file config/application.rb:

config.generators do |g|
  g.template_engine false
  g.test_framework false
  g.assets false
  g.helper false
  g.orm :active_record, migration: false
end

Sử dụng config này, bạn hãy thử lại lệnh generate với controller và model, không cần truyền các tham số nữa xem kết quả thế nào nhé!

Mình nghĩ cũng sẽ rất hữu ích khi bạn tham khảo thêm những tài liệu sau:

  • http://guides.rubyonrails.org/generators.html
  • https://stackoverflow.com/questions/19105723/what-is-the-difference-in-rails-commands-no-test-framework-skip-test-unit
  • http://www.korenlc.com/rails-generate-model-vs-resourse-vs-scaffold/

Mình hi vọng bài viết sẽ giúp ích. Cảm ơn các bạn đã đón đọc.

0