+2

Generators trong Rails & rails generate devise:install

Chắc hẳn các bạn làm Rails cũng đã rất quen thuộc với những câu lệnh như rails generate controller rails generate model cũng như câu lệnh thần thánh rails generate scaffold để tạo ra những ứng dụng demo chỉ trong 1 nốt nhạc (yaoming)

Rồi khi dùng gem như devise thì ngoài chuyện đương nhiên là add gem file :v thì chắc chắn đầu tiên các bạn phải chạy câu lệnh rails generate devise:install

Cũng tương tự như thế với một gem quen thuộc nữa, Rspec thì hiển nhiên phải chạy rails generate rspec:install

Những câu lệnh như thế này sẽ giúp chúng ta setup những thứ cơ bản, cần thiết nhất của gem, như là tạo file config, tạo file migration, tạo controller, model, add routes, ... Tất cả chúng đều được auto. Thât vi diệu :v

Vậy phép thuật nào đã giúp chúng làm được những điều đó? Bạn có muốn tự mình làm một điều tương tự như vậy không?

Chém nguy hiểm thế thôi, chứ Rails đã support bạn tận răng bằng Generators rồi, hè hè *_~ Vậy hnay chúng ta sẽ đi vào tìm hiểu xem Generators nó là cái gì và làm sao để viết được một Generators 😃

Generators là gì?

Theo định nghĩa từ rails guide thì

Rails generators are an essential tool if you plan to improve your workflow.

Đấy, đơn giản vậy thôi :v Generator cung cấp những công cụ giúp bạn cải thiện quy trình làm việc, giúp tăng performance.

Tiếp theo, chúng ta tạo Generators đầu tiên của mình xem sao

Tạo generators đầu tiên

Đầu tiên chúng ta sẽ tạo một cái generators ở trong project rails có sẵn của chúng ta và đơn giản nó sẽ in ra console chữ huyền thoại "Hello world!" =))

Chúng ta sẽ phải tạo thư mục file hello_generator.rb trong thư mục lib/generators như thế này

Trong đó, code như thế này

class HelloGenerator < Rails::Generators::Base
  def say_hello
    puts "Hello world!"
  end
end

Xong !! Check xem trong dự án của m hiện tại có bao nhiêu generators và generators của m đã thực sự chạy được chưa. Bằng cách chạy rails g --help. Kết quả của m sẽ như thế này

Đã thấy generators của m tạo ra 😃 Chạy thử xem sao rails generate hello Và hô biến, Hello world! thần thánh đã xuất hiện

Đơn giản quá phải ko, tên file là gì thì câu lệnh generators sẽ như thế, ở đây là hello_generator.rb file và câu lệnh tương ứng sẽ là rails g hello Bây giờ chúng ta xem qua generators của một gem phổ biến, hầu như không có rails app nào không có là devise xem sao.

Generators của devise

Sau khi add vào Gemfile gem "devise" Chúng ta cần chạy câu lệnh rails generate devise:install Kết quả sẽ là

Xem code như thế nào mà nó lại sinh ra được như thế nhé.

# https://github.com/plataformatec/devise/blob/master/lib/generators/devise/install_generator.rb
require 'rails/generators/base'
require 'securerandom'

module Devise
  module Generators
    MissingORMError = Class.new(Thor::Error)

    class InstallGenerator < Rails::Generators::Base
      source_root File.expand_path("../../templates", __FILE__)

      desc "Creates a Devise initializer and copy locale files to your application."
      class_option :orm

      def copy_initializer
        unless options[:orm]
          raise MissingORMError, <<-ERROR.strip_heredoc
          An ORM must be set to install Devise in your application.

          Be sure to have an ORM like Active Record or Mongoid loaded in your
          app or configure your own at `config/application.rb`.

            config.generators do |g|
              g.orm :your_orm_gem
            end
          ERROR
        end

        template "devise.rb", "config/initializers/devise.rb"
      end

      def copy_locale
        copy_file "../../../config/locales/en.yml", "config/locales/devise.en.yml"
      end

      def show_readme
        readme "README" if behavior == :invoke
      end

      def rails_4?
        Rails::VERSION::MAJOR == 4
      end
    end
  end
end

Đầu tiên, vì nó có cấu trúc module

module Devise
  module Generators

nên nó sẽ có namespace devise khi gọi câu lệnh devise:install

Thứ hai, khi nhìn vào kết quả thấy sẽ tạo file config devise.rb. Nhìn vào code xem sao

# method copy_initializer
template "devise.rb", "config/initializers/devise.rb"

nó sẽ copy file devise.rb ở thư mục template ở https://github.com/plataformatec/devise/blob/master/lib/generators/templates/devise.rb vào file config/initializers/devise.rb trong thư mục source code của m.

Tiếp theo, tạo file locale mặc định devise.en.yml Nhìn vào code nào

#method copy_locale
copy_file "../../../config/locales/en.yml", "config/locales/devise.en.yml"

Đơn giản và dễ hiểu đúng ko nào 😉

Và cuối cùng, màn hình kết quả xuất hiện một đoạn documents

===============================================================================

Some setup you must do manually if you haven't yet:

  1. Ensure you have defined default url options in your environments files. Here is an example of default_url_options appropriate for a development environment in config/environments/development.rb:

    config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }

    In production, :host should be set to the actual host of your application.

  2. Ensure you have defined root_url to something in your config/routes.rb. For example:

    root to: "home#index"

  3. Ensure you have flash messages in app/views/layouts/application.html.erb. For example:

    <%= notice %>

    <%= alert %>

  4. You can copy Devise views (for customization) to your app by running:

    rails g devise:views

===============================================================================

Và code

# method show_readme
readme "README" if behavior == :invoke

Nó sẽ đọc mô tả ở trong file README ở https://github.com/plataformatec/devise/blob/master/lib/generators/templates/README rồi show ra màn hình.

Các bạn có nhận ra là thứ tự các câu lệnh trong một lần generator sẽ tương ứng với thứ tự khai báo các methods trong file không? Vì thế nếu muốn generator ra theo thứ tự như thế nào thì bạn chỉ đơn giản là khai báo các methods trong file generator theo thứ tự đó là được nhé o_o

Cũng khá là rõ ràng và nhẹ nhàng he 😃

Ở trên m đã giới thiệu cách đơn giản để tạo một câu lệnh generators trong rails và đi qua cách tạo câu lệnh rails generate devise:install. Các bạn đã tự tin tạo ra những câu lệnh generators cho riêng m chưa 😉 Nếu chưa thì m sẽ giới thiệu qua một số cái mà generators trong rails nó supports cho m nữa xem sao, sau đó hy vọng bạn sẽ tạo được câu generators ưng ý.

Một vài methods mà Generators hỗ trợ

  1. Add một vài dòng vào Gemfile.
gem "rspec", group: "test", version: "2.1.0"
gem "devise", "1.1.5"

Giống y hệt như những gì mà bạn vẫn copy rồi add vào Gemfile đúng ko. Add một group vào Gemfile

gem_group :development, :test do
  gem "rspec-rails"
end

Cũng không khác gì bạn copy vào đúng ko :v thật quá quen thuộc. rồi cả add source nữa

add_source "http://gems.github.com"
  1. gsub_file
gsub_file 'name_of_file.rb', 'method.to_be_replaced', 'method.the_replacing_code'

Thay thế string method.to_be_replaced bằng method.the_replacing_code trong file name_of_file.rb Rails cũng hỗ trợ dùng Regular Expressions ở đây.

  1. application add một dòng vào file application.rb
application "config.asset_host = 'https://railsviet.com'"
  1. git Thao tác với git
git :init
git add: "."
git commit: "-m First commit!"
git add: "onefile.rb", rm: "badfile.cxx"

Cũng khá là quen thuộc 😃

  1. route Add thêm một route vào file routes.rb
route "resources :people"

Và còn một vài thứ thú vị nữa mà các bạn có thể thao khảo thêm ở để có thể tạo cho m những generators để tăng performance của m, tránh sự nhàm chán với thao tác copy, paste 😃

Các bạn thoải mái thảo luận, comment ở dưới nhé 😃 welcome !!!!

Link gốc: https://railsviet.com/rails-generator-devise-generators/


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí