本教學假設您已閱讀過Rails 入門指南,具備 Rails 的基本知識。
1 建立 Rails 應用程式
首先,讓我們使用 rails new
命令建立一個簡單的 Rails 應用程式。
我們將使用此應用程式來玩耍並探索本指南中描述的所有命令。
如果您的電腦上還沒有安裝 rails gem,您可以輸入 gem install rails
來安裝它。
1.1 rails new
我們傳遞給 rails new
命令的第一個引數是應用程式名稱。
$ rails new my_app
create
create README.md
create Rakefile
create config.ru
create .gitignore
create Gemfile
create app
...
create tmp/cache
...
run bundle install
對於這麼小的命令,Rails 會設定看起來數量龐大的東西!我們現在有了整個 Rails 目錄結構,其中包含所有立即可執行的簡單應用程式所需的程式碼。
如果您希望跳過某些檔案的產生或跳過某些程式庫,您可以將下列任何引數附加到您的 rails new
命令
引數 | 說明 |
---|---|
--skip-git |
跳過 git init、.gitignore 和 .gitattributes |
--skip-docker |
跳過 Dockerfile、.dockerignore 和 bin/docker-entrypoint |
--skip-keeps |
跳過原始碼控制 .keep 檔案 |
--skip-action-mailer |
跳過 Action Mailer 檔案 |
--skip-action-mailbox |
跳過 Action Mailbox gem |
--skip-action-text |
跳過 Action Text gem |
--skip-active-record |
跳過 Active Record 檔案 |
--skip-active-job |
跳過 Active Job |
--skip-active-storage |
跳過 Active Storage 檔案 |
--skip-action-cable |
跳過 Action Cable 檔案 |
--skip-asset-pipeline |
跳過資產管線 |
--skip-javascript |
跳過 JavaScript 檔案 |
--skip-hotwire |
跳過 Hotwire 整合 |
--skip-jbuilder |
跳過 jbuilder gem |
--skip-test |
跳過測試檔案 |
--skip-system-test |
跳過系統測試檔案 |
--skip-bootsnap |
跳過 bootsnap gem |
--skip-dev-gems |
跳過新增開發 gem |
--skip-rubocop |
跳過 RuboCop 設定 |
這些只是 rails new
接受的部分選項。如需完整選項列表,請輸入 rails new --help
。
1.2 預先設定不同的資料庫
在建立新的 Rails 應用程式時,您可以指定應用程式將使用的資料庫類型。這將為您節省幾分鐘的時間,而且肯定可以減少許多按鍵次數。
讓我們看看 --database=postgresql
選項會為我們做什麼
$ rails new petstore --database=postgresql
create
create app/controllers
create app/helpers
...
讓我們看看它在我們的 config/database.yml
中放入了什麼
# PostgreSQL. Versions 9.3 and up are supported.
#
# Install the pg driver:
# gem install pg
# On macOS with Homebrew:
# gem install pg -- --with-pg-config=/usr/local/bin/pg_config
# On Windows:
# gem install pg
# Choose the win32 build.
# Install PostgreSQL and put its /bin directory on your path.
#
# Configure Using Gemfile
# gem "pg"
#
default: &default
adapter: postgresql
encoding: unicode
# For details on connection pooling, see Rails configuration guide
# https://rails-guides.dev.org.tw/configuring.html#database-pooling
pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %>
development:
<<: *default
database: petstore_development
...
它產生了與我們選擇的 PostgreSQL 相對應的資料庫設定。
2 命令列基礎
以下幾個命令對於您日常使用 Rails 至關重要。按照您可能使用它們的頻率順序排列如下:
bin/rails console
bin/rails server
bin/rails test
bin/rails generate
bin/rails db:migrate
bin/rails db:create
bin/rails routes
bin/rails dbconsole
rails new app_name
您可以輸入 rails --help
來取得可用的 Rails 命令清單,這通常取決於您目前的目錄。每個命令都有說明,應該可以幫助您找到需要的東西。
$ 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")
...
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 ...
assets:clean[keep] Remove old compiled assets
assets:clobber Remove compiled assets
assets:environment Load asset compile environment
assets:precompile Compile all the assets ...
...
db:fixtures:load Load fixtures into the ...
db:migrate Migrate the database ...
db:migrate:status Display status of migrations
db:rollback Roll the schema back to ...
db:schema:cache:clear Clears 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 ...
db:schema:load Load a database schema file (either db/schema.rb or db/structure.sql ...
db:seed Load the seed data ...
db:version Retrieve the current schema ...
...
restart Restart app by touching ...
tmp:create Create tmp directories ...
2.1 bin/rails server
bin/rails server
命令會啟動一個名為 Puma 的 Web 伺服器,該伺服器與 Rails 捆綁在一起。每當您想透過網頁瀏覽器存取您的應用程式時,都會使用此命令。
無需進一步處理,bin/rails server
就會執行我們全新的 Rails 應用程式
$ cd my_app
$ bin/rails server
=> Booting Puma
=> Rails 8.0.0 application starting in development
=> Run `bin/rails server --help` for more startup options
Puma starting in single mode...
* Puma version: 6.4.0 (ruby 3.1.3-p185) ("The Eagle of Durango")
* Min threads: 5
* Max threads: 5
* Environment: development
* PID: 5295
* Listening on http://127.0.0.1:3000
* Listening on http://[::1]:3000
Use Ctrl-C to stop
只需三個命令,我們就啟動了一個監聽 3000 埠的 Rails 伺服器。前往您的瀏覽器並開啟 http://localhost:3000,您將會看到一個基本的 Rails 應用程式正在執行。
您也可以使用別名 "s" 來啟動伺服器:bin/rails s
。
可以使用 -p
選項在不同的埠上執行伺服器。可以使用 -e
來變更預設的開發環境。
$ bin/rails server -e production -p 4000
-b
選項會將 Rails 繫結到指定的 IP,預設為 localhost。您可以傳遞 -d
選項以將伺服器作為守護程式執行。
2.2 bin/rails generate
bin/rails generate
命令會使用範本來建立許多東西。單獨執行 bin/rails generate
會列出可用的產生器
您也可以使用別名 "g" 來叫用產生器命令:bin/rails g
。
$ bin/rails generate
Usage:
bin/rails generate GENERATOR [args] [options]
...
...
Please choose a generator below.
Rails:
assets
channel
controller
generator
...
...
您可以透過產生器 gem、您無疑會安裝的外掛程式的部分來安裝更多產生器,甚至可以建立自己的產生器!
使用產生器將透過撰寫**樣板程式碼**來節省您大量的時間,這些程式碼是應用程式運作所必需的。
讓我們使用控制器產生器來建立自己的控制器。但是我們應該使用什麼命令?讓我們詢問產生器
所有 Rails 控制台實用工具都有說明文字。與大多數 *nix 實用工具一樣,您可以嘗試在結尾新增 --help
或 -h
,例如 bin/rails server --help
。
$ bin/rails generate controller
Usage:
bin/rails generate controller NAME [action action] [options]
...
...
Description:
...
To create a controller within a module, specify the controller name as a path like 'parent_module/controller_name'.
...
Example:
`bin/rails generate controller CreditCards open debit credit close`
Credit card controller with URLs like /credit_cards/debit.
Controller: app/controllers/credit_cards_controller.rb
Test: test/controllers/credit_cards_controller_test.rb
Views: app/views/credit_cards/debit.html.erb [...]
Helper: app/helpers/credit_cards_helper.rb
控制器產生器預期參數的形式為 generate controller ControllerName action1 action2
。讓我們建立一個 Greetings
控制器,其動作為 hello,它會對我們說一些好聽的話。
$ bin/rails generate controller Greetings hello
create app/controllers/greetings_controller.rb
route get 'greetings/hello'
invoke erb
create app/views/greetings
create app/views/greetings/hello.html.erb
invoke test_unit
create test/controllers/greetings_controller_test.rb
invoke helper
create app/helpers/greetings_helper.rb
invoke test_unit
這一切都產生了什麼?它確保我們的應用程式中存在一堆目錄,並建立了一個控制器檔案、一個視圖檔案、一個功能測試檔案、視圖的輔助方法、一個 JavaScript 檔案和一個樣式表檔案。
檢查控制器並稍微修改一下(在 app/controllers/greetings_controller.rb
中)
class GreetingsController < ApplicationController
def hello
@message = "Hello, how are you today?"
end
end
然後是視圖,以顯示我們的訊息(在 app/views/greetings/hello.html.erb
中)
<h1>A Greeting for You!</h1>
<p><%= @message %></p>
使用 bin/rails server
啟動您的伺服器。
$ bin/rails server
=> Booting Puma...
URL 將為 http://localhost:3000/greetings/hello。
對於一般的 Rails 應用程式,您的 URL 通常會遵循 http://(host)/(controller)/(action) 的模式,而像 http://(host)/(controller) 這樣的 URL 會點擊該控制器的 index 動作。
Rails 也提供資料模型產生器。
$ bin/rails generate model
Usage:
bin/rails generate model NAME [field[:type][:index] field[:type][:index]] [options]
...
ActiveRecord options:
[--migration], [--no-migration] # Indicates when to generate migration
# Default: true
...
Description:
Generates a new model. Pass the model name, either CamelCased or
under_scored, and an optional list of attribute pairs as arguments.
...
如需 type
參數可用欄位類型的列表,請參閱 SchemaStatements
模組的 add_column 方法的API 文件。index
參數會為欄位產生相應的索引。
但是,我們不直接產生模型(我們稍後會執行),而是設定一個 scaffold。Rails 中的 scaffold 是模型的完整集合、該模型的資料庫遷移、用於操作它的控制器、用於檢視和操作資料的視圖,以及上述每個項目的測試套件。
我們將設定一個名為「HighScore」的簡單資源,該資源將追蹤我們在電子遊戲中獲得的最高分數。
$ bin/rails generate scaffold HighScore game:string score:integer
invoke active_record
create db/migrate/20190416145729_create_high_scores.rb
create app/models/high_score.rb
invoke test_unit
create test/models/high_score_test.rb
create test/fixtures/high_scores.yml
invoke resource_route
route resources :high_scores
invoke scaffold_controller
create app/controllers/high_scores_controller.rb
invoke erb
create app/views/high_scores
create app/views/high_scores/index.html.erb
create app/views/high_scores/edit.html.erb
create app/views/high_scores/show.html.erb
create app/views/high_scores/new.html.erb
create app/views/high_scores/_form.html.erb
invoke test_unit
create test/controllers/high_scores_controller_test.rb
create test/system/high_scores_test.rb
invoke helper
create app/helpers/high_scores_helper.rb
invoke test_unit
invoke jbuilder
create app/views/high_scores/index.json.jbuilder
create app/views/high_scores/show.json.jbuilder
create app/views/high_scores/_high_score.json.jbuilder
產生器會為 HighScore 建立模型、視圖、控制器、資源路由和資料庫遷移(用於建立 high_scores
資料表)。它還會為這些新增測試。
遷移需要我們進行遷移,也就是執行一些 Ruby 程式碼(上述輸出中的 20190416145729_create_high_scores.rb
檔案),以修改我們資料庫的結構。哪個資料庫呢?就是當我們執行 bin/rails db:migrate
命令時,Rails 會為您建立的 SQLite3 資料庫。我們稍後會詳細討論這個命令。
$ bin/rails db:migrate
== CreateHighScores: migrating ===============================================
-- create_table(:high_scores)
-> 0.0017s
== CreateHighScores: migrated (0.0019s) ======================================
讓我們來談談單元測試。單元測試是用來測試並對程式碼做出斷言的程式碼。在單元測試中,我們會取一小段程式碼,例如模型的一個方法,然後測試它的輸入和輸出。單元測試是你的朋友。你越早接受單元測試能大幅提升你的生活品質這個事實,就越好。真的。請參閱測試指南,深入了解單元測試。
讓我們來看看 Rails 為我們建立的介面。
$ bin/rails server
前往您的瀏覽器並開啟http://localhost:3000/high_scores,現在我們可以建立新的高分(太空侵略者 55,160 分!)
2.3 bin/rails console
console
命令可讓您從命令列與您的 Rails 應用程式互動。在底層,bin/rails console
使用 IRB,所以如果您曾經使用過它,您會覺得很熟悉。這對於測試程式碼的快速想法,以及在不接觸網站的情況下更改伺服器端的資料很有用。
您也可以使用別名 "c" 來呼叫主控台:bin/rails c
。
您可以指定 console
命令應該運作的環境。
$ bin/rails console -e staging
如果您想測試一些程式碼而不更改任何資料,您可以透過呼叫 bin/rails console --sandbox
來完成。
$ bin/rails console --sandbox
Loading development environment in sandbox (Rails 8.0.0)
Any modifications you make will be rolled back on exit
irb(main):001:0>
2.3.1 app
和 helper
物件
在 bin/rails console
內,您可以存取 app
和 helper
實例。
透過 app
方法,您可以存取具名的路由輔助方法,以及執行請求。
irb> app.root_path
=> "/"
irb> app.get _
Started GET "/" for 127.0.0.1 at 2014-06-19 10:41:57 -0300
...
透過 helper
方法,您可以存取 Rails 和您的應用程式的輔助方法。
irb> helper.time_ago_in_words 30.days.ago
=> "about 1 month"
irb> helper.my_custom_helper
=> "my custom helper"
2.4 bin/rails dbconsole
bin/rails dbconsole
會找出您正在使用的資料庫,並將您丟入您會使用的命令列介面中(並找出要給它的命令列參數!)。它支援 MySQL(包含 MariaDB)、PostgreSQL 和 SQLite3。
您也可以使用別名 "db" 來呼叫 dbconsole:bin/rails db
。
如果您正在使用多個資料庫,bin/rails dbconsole
預設會連線到主要資料庫。您可以使用 --database
或 --db
來指定要連線的資料庫。
$ bin/rails dbconsole --database=animals
2.5 bin/rails runner
runner
會在非互動式的 Rails 應用程式環境中執行 Ruby 程式碼,而無需開啟 Rails console
。例如
$ bin/rails runner "Model.long_running_method"
您也可以使用別名 "r" 來呼叫 runner:bin/rails r
。
您可以使用 -e
參數指定 runner
命令應該運作的環境。
$ bin/rails runner -e staging "Model.long_running_method"
您甚至可以使用 runner 執行寫在檔案中的 ruby 程式碼。
$ bin/rails runner lib/code_to_be_run.rb
預設情況下,rails runner
指令碼會自動使用 Rails Executor 包裝,這有助於回報未捕獲的例外情況,例如排程任務。
因此,執行 rails runner lib/long_running_scripts.rb
在功能上等同於以下內容
Rails.application.executor.wrap do
# executes code inside lib/long_running_scripts.rb
end
您可以使用 --skip-executor
選項來選擇退出此行為。
$ bin/rails runner --skip-executor lib/long_running_script.rb
2.6 bin/rails destroy
將 destroy
想成是 generate
的相反。它會找出 generate 所做的操作,然後將其撤銷。
您也可以使用別名 "d" 來呼叫 destroy 命令:bin/rails d
。
$ bin/rails generate model Oops
invoke active_record
create db/migrate/20120528062523_create_oops.rb
create app/models/oops.rb
invoke test_unit
create test/models/oops_test.rb
create test/fixtures/oops.yml
$ bin/rails destroy model Oops
invoke active_record
remove db/migrate/20120528062523_create_oops.rb
remove app/models/oops.rb
invoke test_unit
remove test/models/oops_test.rb
remove test/fixtures/oops.yml
2.7 bin/rails about
bin/rails about
會提供關於 Ruby、RubyGems、Rails、Rails 子元件、您的應用程式資料夾、目前 Rails 環境名稱、您的應用程式資料庫配接器和結構描述版本的版本號碼資訊。當您需要尋求協助、檢查安全性修補程式是否會影響您,或當您需要現有 Rails 安裝的一些統計資料時,這很有用。
$ bin/rails about
About your application's environment
Rails version 8.0.0
Ruby version 3.2.0 (x86_64-linux)
RubyGems version 3.3.7
Rack version 3.0.8
JavaScript Runtime Node.js (V8)
Middleware: ActionDispatch::HostAuthorization, Rack::Sendfile, ActionDispatch::Static, ActionDispatch::Executor, ActionDispatch::ServerTiming, ActiveSupport::Cache::Strategy::LocalCache::Middleware, Rack::Runtime, Rack::MethodOverride, ActionDispatch::RequestId, ActionDispatch::RemoteIp, Sprockets::Rails::QuietAssets, Rails::Rack::Logger, ActionDispatch::ShowExceptions, WebConsole::Middleware, ActionDispatch::DebugExceptions, ActionDispatch::ActionableExceptions, ActionDispatch::Reloader, ActionDispatch::Callbacks, ActiveRecord::Migration::CheckPending, ActionDispatch::Cookies, ActionDispatch::Session::CookieStore, ActionDispatch::Flash, ActionDispatch::ContentSecurityPolicy::Middleware, ActionDispatch::PermissionsPolicy::Middleware, Rack::Head, Rack::ConditionalGet, Rack::ETag, Rack::TempfileReaper
Application root /home/foobar/my_app
Environment development
Database adapter sqlite3
Database schema version 20180205173523
2.8 bin/rails assets:
您可以使用 bin/rails assets:precompile
來預先編譯 app/assets
中的資源,並使用 bin/rails assets:clean
來移除較舊的已編譯資源。assets:clean
命令允許滾動部署,在建立新資源時,可能仍會連結到舊資源。
如果您想要完全清除 public/assets
,您可以使用 bin/rails assets:clobber
。
2.9 bin/rails db:
db:
rails 命名空間中最常見的命令是 migrate
和 create
,並且嘗試所有遷移 rails 命令(up
、down
、redo
、reset
)會有回報。bin/rails db:version
在進行疑難排解時很有用,它會告訴您資料庫的目前版本。
有關遷移的更多資訊,請參閱遷移指南。
2.10 bin/rails notes
bin/rails notes
會在您的程式碼中搜尋以特定關鍵字開頭的註解。您可以參考 bin/rails notes --help
來取得有關使用方式的資訊。
預設情況下,它會在 app
、config
、db
、lib
和 test
目錄中,搜尋副檔名為 .builder
、.rb
、.rake
、.yml
、.yaml
、.ruby
、.css
、.js
和 .erb
的檔案中,包含 FIXME、OPTIMIZE 和 TODO 註解。
$ bin/rails notes
app/controllers/admin/users_controller.rb:
* [ 20] [TODO] any other way to do this?
* [132] [FIXME] high priority for next deploy
lib/school.rb:
* [ 13] [OPTIMIZE] refactor this code to make it faster
* [ 17] [FIXME]
2.10.1 註解
您可以使用 --annotations
參數傳遞特定的註解。預設情況下,它會搜尋 FIXME、OPTIMIZE 和 TODO。請注意,註解是區分大小寫的。
$ bin/rails notes --annotations FIXME RELEASE
app/controllers/admin/users_controller.rb:
* [101] [RELEASE] We need to look at this before next release
* [132] [FIXME] high priority for next deploy
lib/school.rb:
* [ 17] [FIXME]
2.10.2 標籤
您可以使用 config.annotations.register_tags
來新增要搜尋的更多預設標籤。它會接收標籤的列表。
config.annotations.register_tags("DEPRECATEME", "TESTME")
$ bin/rails notes
app/controllers/admin/users_controller.rb:
* [ 20] [TODO] do A/B testing on this
* [ 42] [TESTME] this needs more functional tests
* [132] [DEPRECATEME] ensure this method is deprecated in next release
2.10.3 目錄
您可以使用 config.annotations.register_directories
來新增要搜尋的更多預設目錄。它會接收目錄名稱的列表。
config.annotations.register_directories("spec", "vendor")
$ bin/rails notes
app/controllers/admin/users_controller.rb:
* [ 20] [TODO] any other way to do this?
* [132] [FIXME] high priority for next deploy
lib/school.rb:
* [ 13] [OPTIMIZE] Refactor this code to make it faster
* [ 17] [FIXME]
spec/models/user_spec.rb:
* [122] [TODO] Verify the user that has a subscription works
vendor/tools.rb:
* [ 56] [TODO] Get rid of this dependency
2.10.4 副檔名
您可以使用 config.annotations.register_extensions
來新增要搜尋的更多預設檔案副檔名。它會接收副檔名的列表及其對應的 regex 來比對。
config.annotations.register_extensions("scss", "sass") { |annotation| /\/\/\s*(#{annotation}):?\s*(.*)$/ }
$ bin/rails notes
app/controllers/admin/users_controller.rb:
* [ 20] [TODO] any other way to do this?
* [132] [FIXME] high priority for next deploy
app/assets/stylesheets/application.css.sass:
* [ 34] [TODO] Use pseudo element for this class
app/assets/stylesheets/application.css.scss:
* [ 1] [TODO] Split into multiple components
lib/school.rb:
* [ 13] [OPTIMIZE] Refactor this code to make it faster
* [ 17] [FIXME]
spec/models/user_spec.rb:
* [122] [TODO] Verify the user that has a subscription works
vendor/tools.rb:
* [ 56] [TODO] Get rid of this dependency
2.11 bin/rails routes
bin/rails routes
會列出您所有定義的路由,這對於追蹤應用程式中的路由問題,或讓您對您嘗試熟悉的應用程式中的 URL 有良好的概述很有用。
2.12 bin/rails test
關於 Rails 中單元測試的良好描述,請參閱Rails 應用程式測試指南
Rails 附帶一個稱為 minitest 的測試框架。Rails 的穩定性歸功於測試的使用。test:
命名空間中可用的命令有助於執行您希望撰寫的不同測試。
2.13 bin/rails tmp:
Rails.root/tmp
目錄就像 *nix 的 /tmp 目錄一樣,是暫存檔案(例如程序 ID 檔案和快取的動作)的存放位置。
tmp:
命名空間的命令將協助您清除和建立 Rails.root/tmp
目錄
bin/rails tmp:cache:clear
會清除tmp/cache
。bin/rails tmp:sockets:clear
會清除tmp/sockets
。bin/rails tmp:screenshots:clear
會清除tmp/screenshots
。bin/rails tmp:clear
會清除所有快取、socket 和螢幕截圖檔案。bin/rails tmp:create
會為快取、socket 和 pids 建立 tmp 目錄。
2.14 其他
bin/rails initializers
會依 Rails 呼叫的順序列印所有已定義的初始化程式。bin/rails middleware
會列出為您的應用程式啟用的 Rack 中介軟體堆疊。bin/rails stats
非常適合查看您程式碼的統計資料,顯示例如 KLOC(千行程式碼)和您的程式碼與測試比例。bin/rails secret
會給您一個偽隨機金鑰,用於您的會期機密。bin/rails time:zones:all
會列出 Rails 所知道的所有時區。bin/rails boot
會啟動應用程式並退出。
2.15 自訂 Rake 任務
自訂 rake 任務具有 .rake
副檔名,並放置在 Rails.root/lib/tasks
中。您可以使用 bin/rails generate task
命令建立這些自訂 rake 任務。
desc "I am short, but comprehensive description for my cool task"
task task_name: [:prerequisite_task, :another_task_we_depend_on] do
# All your magic here
# Any valid Ruby code is allowed
end
將參數傳遞給您的自訂 rake 任務
task :task_name, [:arg_1] => [:prerequisite_1, :prerequisite_2] do |task, args|
argument_1 = args.arg_1
end
您可以透過將任務放置在命名空間中來將任務分組
namespace :db do
desc "This task does nothing"
task :nothing do
# Seriously, nothing
end
end
任務的呼叫會如下所示
$ bin/rails task_name
$ bin/rails "task_name[value 1]" # entire argument string should be quoted
$ bin/rails "task_name[value 1,value2,value3]" # separate multiple args with a comma
$ bin/rails db:nothing
如果您需要與您的應用程式模型互動、執行資料庫查詢等等,您的任務應該依賴 environment
任務,該任務將載入您的應用程式程式碼。
task task_that_requires_app_code: [:environment] do
User.create!
end