はじめに
Rails Tips の 48 回目です。昨日は RSpec と Guard をインストールしました。次に進みたいところですが、まだ view が erb のままでした。小林研では記述を簡単にするために、erb ではなく haml を使っています。今回は、既存の erb を haml に変更したいと思います。
erb から haml に変換
haml-rails が入っていると rails のコマンドで erb ファイルを haml に変換できます。rails のコマンドはいつものように help で確認します。
$ rails --help Usage: bin/rails COMMAND [options] You must specify a command. The most common commands are: generate Generate new code (short-cut alias: "g") console Start the Rails console (short-cut alias: "c") server Start the Rails server (short-cut alias: "s") test Run tests except system tests (short-cut alias: "t") test:system Run system tests dbconsole Start a console for the database specified in config/database.yml (short-cut alias: "db") plugin new Create a new Rails railtie or engine All commands can be run with -h (or --help) for more information. In addition to those commands, there are: about List versions of all Rails frameworks and the environment action_mailbox:ingress:exim Relay an inbound email from Exim to Action Mailbox (URL and INGRESS_PASSWORD required) action_mailbox:ingress:postfix Relay an inbound email from Postfix to Action Mailbox (URL and INGRESS_PASSWORD required) action_mailbox:ingress:qmail Relay an inbound email from Qmail to Action Mailbox (URL and INGRESS_PASSWORD required) action_mailbox:install Install Action Mailbox and its dependencies action_mailbox:install:migrations Copy migrations from action_mailbox to application action_text:install Copy over the migration, stylesheet, and JavaScript files action_text:install:migrations Copy migrations from action_text to application active_storage:install Copy over the migration needed to the application app:template Apply the template supplied by LOCATION=(/path/to/template) or URL app:update Update configs and some other initially generated files (or use just update:configs or update:bin) assets:clean Removes old files in config.assets.output_path assets:clobber Remove config.assets.output_path assets:precompile Compile all the assets from config.assets.paths assets:reveal Print all the assets available in config.assets.paths assets:reveal:full Print the full path of assets available in config.assets.paths cache_digests:dependencies Lookup first-level dependencies for TEMPLATE (like messages/show or comments/_comment.html) cache_digests:nested_dependencies Lookup nested dependencies for TEMPLATE (like messages/show or comments/_comment.html) credentials:diff Enroll/disenroll in decrypted diffs of credentials using git credentials:edit Open the decrypted credentials in `$VISUAL` or `$EDITOR` for editing credentials:show Show the decrypted credentials db:create Create the database from DATABASE_URL or config/database.yml for the current RAILS_ENV (use db:create:all to create all databases in the config). With... db:drop Drop the database from DATABASE_URL or config/database.yml for the current RAILS_ENV (use db:drop:all to drop all databases in the config). Without RA... db:encryption:init Generate a set of keys for configuring Active Record encryption in a given environment db:environment:set Set the environment value for the database db:fixtures:load Load fixtures into the current environment's database db:migrate Migrate the database (options: VERSION=x, VERBOSE=false, SCOPE=blog) db:migrate:down Run the "down" for a given migration VERSION db:migrate:redo Roll back the database one migration and re-migrate up (options: STEP=x, VERSION=x) db:migrate:status Display status of migrations db:migrate:up Run the "up" for a given migration VERSION db:prepare Run setup if database does not exist, or run migrations if it does db:reset Drop and recreate all databases from their schema for the current environment and load the seeds db:rollback Roll the schema back to the previous version (specify steps w/ STEP=n) db:schema:cache:clear Clear a db/schema_cache.yml file db:schema:cache:dump Create a db/schema_cache.yml file db:schema:dump Create a database schema file (either db/schema.rb or db/structure.sql, depending on `ENV['SCHEMA_FORMAT']` or `config.active_record.schema_format`) db:schema:load Load a database schema file (either db/schema.rb or db/structure.sql, depending on `ENV['SCHEMA_FORMAT']` or `config.active_record.schema_format`) int... db:seed Load the seed data from db/seeds.rb db:seed:replant Truncate tables of each database for current environment and load the seeds db:setup Create all databases, load all schemas, and initialize with the seed data (use db:reset to also drop all databases first) db:system:change Change `config/database.yml` and your database gem to the target database db:version Retrieve the current schema version number destroy Remove code generated by `bin/rails generate` dev:cache Toggle development mode caching on/off encrypted:edit Open the decrypted file in `$VISUAL` or `$EDITOR` for editing encrypted:show Show the decrypted contents of the file haml:erb2haml Convert html.erb to html.haml each file in app/views importmap:install Setup Importmap for the app initializers Print out all defined initializers in the order they are invoked by Rails. log:clear Truncate all/specified *.log files in log/ to zero bytes (specify which logs with LOGS=test,development) middleware Print out your Rack middleware stack notes Show comments in your code annotated with FIXME, OPTIMIZE, and TODO restart Restart app by touching tmp/restart.txt routes List all the defined routes runner Run Ruby code in the context of your application secret Generate a cryptographically secure secret key (this is typically used to generate a secret for cookie sessions). secrets:edit **deprecated** Open the secrets in `$VISUAL` or `$EDITOR` for editing secrets:show **deprecated** Show the decrypted secrets spec Run all specs in spec directory (excluding plugin specs) stats Report code statistics (KLOCs, etc) from the application or engine stimulus:install Install Stimulus into the app stimulus:install:bun Install Stimulus on an app running bun stimulus:install:importmap Install Stimulus on an app running importmap-rails stimulus:install:node Install Stimulus on an app running node stimulus:manifest:display Show the current Stimulus manifest (all installed controllers) stimulus:manifest:update Update the Stimulus manifest (will overwrite controllers/index.js) test:all Run all tests, including system tests test:channels Run tests in test/channels test:controllers Run tests in test/controllers test:functionals Run tests in test/controllers, test/mailers, and test/functional test:generators Run tests in test/lib/generators test:helpers Run tests in test/helpers test:integration Run tests in test/integration test:jobs Run tests in test/jobs test:mailboxes Run tests in test/mailboxes test:mailers Run tests in test/mailers test:models Run tests in test/models test:units Run tests in test/models, test/helpers, and test/unit time:zones[country_or_offset] List all time zones, list by two-letter country code (`bin/rails time:zones[US]`), or list by UTC offset (`bin/rails time:zones[-8]`) tmp:clear Clear cache, socket and screenshot files from tmp/ (narrow w/ tmp:cache:clear, tmp:sockets:clear, tmp:screenshots:clear) tmp:create Create tmp directories for cache, sockets, and pids turbo:install Install Turbo into the app turbo:install:bun Install Turbo into the app with bun turbo:install:importmap Install Turbo into the app with asset pipeline turbo:install:node Install Turbo into the app with webpacker turbo:install:redis Switch on Redis and use it in development version Show the Rails version yarn:install Install all JavaScript dependencies as specified via Yarn zeitwerk:check Check project structure for Zeitwerk compatibility
最初に RSpec をインストールします。たまにしか実行しないとすぐに忘れてしまうので、 --help
で確認しましょう。 rspec:install
というジェネレータがありますね。検索するよりまずはヘルプを見るのが一番です。
$ bin/rails g --help Usage: bin/rails generate GENERATOR [args] [options] General options: -h, [--help] # Print generator's options and usage -p, [--pretend] # Run but do not make any changes -f, [--force] # Overwrite files that already exist -s, [--skip] # Skip files that already exist -q, [--quiet] # Suppress status output Please choose a generator below. Rails: application_record benchmark channel controller generator helper integration_test jbuilder job mailbox mailer migration model resource scaffold scaffold_controller system_test task ActiveRecord: active_record:application_record active_record:multi_db Erb: erb:controller erb:mailer erb:scaffold Haml: haml:application_layout Rspec: rspec:channel rspec:controller rspec:feature rspec:generator rspec:helper rspec:install rspec:integration rspec:job rspec:mailbox rspec:mailer rspec:model rspec:request rspec:scaffold rspec:system rspec:view Stimulus: stimulus TestUnit: test_unit:channel test_unit:controller test_unit:generator test_unit:helper test_unit:install test_unit:integration test_unit:job test_unit:mailbox test_unit:mailer test_unit:model test_unit:plugin test_unit:scaffold test_unit:system
ここから haml:erb2haml を rails に指示すれば erb から haml に変換できるようです。
> rails haml:erb2haml -------------------------------------------------------------------------------- Generating HAML for app/views/layouts/application.html.erb... rbenv: html2haml: command not found The `html2haml' command exists in these Ruby versions: 3.1.1 Generating HAML for app/views/layouts/mailer.html.erb... rbenv: html2haml: command not found The `html2haml' command exists in these Ruby versions: 3.1.1 Generating HAML for app/views/layouts/mailer.text.erb... rbenv: html2haml: command not found The `html2haml' command exists in these Ruby versions: 3.1.1 -------------------------------------------------------------------------------- HAML generated for the following files: app/views/layouts/application.html.erb app/views/layouts/mailer.html.erb app/views/layouts/mailer.text.erb -------------------------------------------------------------------------------- Would you like to delete the original .erb files? (This is not recommended unless you are under version control.) (y/n) y Deleting original .erb files. -------------------------------------------------------------------------------- Task complete!
実行しましたが、html2haml コマンドが存在しないとなりました。html2haml をインストールする必要があるようです。開発時にしか使わないので、Gemfile の development, test の一番下に入れました。
gem "haml-lint" gem "html2haml" end
bundle すると正しくインストールされました。
$ bundle Fetching gem metadata from https://rubygems.org/......... Resolving dependencies... Fetching erubis 2.7.0 Fetching sexp_processor 4.17.1 Installing erubis 2.7.0 Installing sexp_processor 4.17.1 Fetching ruby_parser 3.21.0 Installing ruby_parser 3.21.0 Fetching html2haml 2.3.0 Installing html2haml 2.3.0 Bundle complete! 21 Gemfile dependencies, 122 gems now installed. Use `bundle info [gemname]` to see where a bundled gem is installed.
もう一度実行すると、以下のように haml が生成されました。
$ rails haml:erb2haml -------------------------------------------------------------------------------- Generating HAML for app/views/layouts/application.html.erb... Generating HAML for app/views/layouts/mailer.html.erb... Generating HAML for app/views/layouts/mailer.text.erb... -------------------------------------------------------------------------------- HAML generated for the following files: app/views/layouts/application.html.erb app/views/layouts/mailer.html.erb app/views/layouts/mailer.text.erb -------------------------------------------------------------------------------- Would you like to delete the original .erb files? (This is not recommended unless you are under version control.) (y/n) n Please remember to delete your .erb files once you have ensured they were translated correctly. -------------------------------------------------------------------------------- Task complete!
実際に application.html.haml は以下のようになりました。
!!! %html %head %meta{:content => "text/html; charset=UTF-8", "http-equiv" => "Content-Type"}/ %title HkobBlog %meta{:content => "width=device-width,initial-scale=1", :name => "viewport"}/ = csrf_meta_tags = csp_meta_tag = stylesheet_link_tag "application", "data-turbo-track": "reload" %body = yield
このままだとハッシュの記述が古いので、以下のように書き換えます。RubyMine であれば Opt + Return で簡単に変更してくれます。
!!! %html %head %meta{content: "text/html; charset=UTF-8", "http-equiv" => "Content-Type"}/ %title HkobBlog %meta{content: "width=device-width,initial-scale=1", name: "viewport"}/ = csrf_meta_tags = csp_meta_tag = stylesheet_link_tag "application", "data-turbo-track": "reload" %body = yield
おわりに
erb を haml に変換することで、html の閉じるタグのことを気にする必要がなくなるので、view の記述が非常に簡単になりますね。