1 設定
目前,Rails 外掛被構建為 gems,gemified plugins。它們可以被共享 如果需要,使用 RubyGems 和 Bundler 的不同 Rails 應用程式。
1.1 產生一個 gemified 外掛。
Rails 附帶一個 rails plugin new
命令,它建立一個
用於開發具有能力的任何型別的 Rails 擴充套件的骨架
使用虛擬 Rails 應用程式執行整合測試。建立您的
帶有命令的外掛:
$ rails plugin new yaffle
通過尋求幫助來檢視用法和選項:
$ rails plugin new --help
2 測試您新產生的外掛
您可以導航到包含外掛的目錄,執行 bundle install
命令
並使用 bin/test
命令執行產生的測試。
你應該看到:
1 runs, 1 assertions, 0 failures, 0 errors, 0 skips
這將告訴您一切都已正確產生,您已準備好開始新增功能。
3 擴充套件核心類
本節將解釋如何向 String 新增一個方法,該方法將在您的 Rails 應用程式中的任何位置可用。
在本例中,您將向 String 新增一個名為 to_squawk
的方法。首先,建立一個包含幾個斷言的新測試檔案:
# yaffle/test/core_ext_test.rb
require "test_helper"
class CoreExtTest < ActiveSupport::TestCase
def test_to_squawk_prepends_the_word_squawk
assert_equal "squawk! Hello World", "Hello World".to_squawk
end
end
執行 bin/test
來執行測試。這個測試應該會失敗,因為我們還沒有實現 to_squawk
方法:
E
Error:
CoreExtTest#test_to_squawk_prepends_the_word_squawk:
NoMethodError: undefined method `to_squawk' for "Hello World":String
bin/test /path/to/yaffle/test/core_ext_test.rb:4
.
Finished in 0.003358s, 595.6483 runs/s, 297.8242 assertions/s.
2 runs, 1 assertions, 0 failures, 1 errors, 0 skips
太好了 - 現在您已準備好開始開發。
在 lib/yaffle.rb
中,新增 require "yaffle/core_ext"
:
# yaffle/lib/yaffle.rb
require "yaffle/railtie"
require "yaffle/core_ext"
module Yaffle
# Your code goes here...
end
最後,建立 core_ext.rb
檔案並新增 to_squawk
方法:
# yaffle/lib/yaffle/core_ext.rb
class String
def to_squawk
"squawk! #{self}".strip
end
end
要測試您的方法是否按規定執行,請使用外掛目錄中的 bin/test
執行單元測試。
2 runs, 2 assertions, 0 failures, 0 errors, 0 skips
要在 action 中看到這一點,請切換到 test/dummy
目錄,啟動 bin/rails console
,然後開始尖叫:
irb> "Hello World".to_squawk
=> "squawk! Hello World"
4 向 Active Record 新增“acts_as”方法
外掛中的一個常見模式是向 models 新增一個名為 acts_as_something
的方法。在這種情況下,你
想編寫一個名為 acts_as_yaffle
的方法,將 squawk
方法新增到您的 Active Record models。
首先,設定您的檔案,以便您擁有:
# yaffle/test/acts_as_yaffle_test.rb
require "test_helper"
class ActsAsYaffleTest < ActiveSupport::TestCase
end
# yaffle/lib/yaffle.rb
require "yaffle/railtie"
require "yaffle/core_ext"
require "yaffle/acts_as_yaffle"
module Yaffle
# Your code goes here...
end
# yaffle/lib/yaffle/acts_as_yaffle.rb
module Yaffle
module ActsAsYaffle
end
end
4.1 新增類方法
這個外掛會期望你已經在你的 model 中添加了一個名為 last_squawk
的方法。但是,那
外掛使用者可能已經在他們使用的名為 last_squawk
的 model 上定義了一個方法
為了別的東西。該外掛將允許通過新增名為 yaffle_text_field
的類方法來更改名稱。
首先,編寫一個失敗的測試來顯示您想要的行為:
# yaffle/test/acts_as_yaffle_test.rb
require "test_helper"
class ActsAsYaffleTest < ActiveSupport::TestCase
def test_a_hickwalls_yaffle_text_field_should_be_last_squawk
assert_equal "last_squawk", Hickwall.yaffle_text_field
end
def test_a_wickwalls_yaffle_text_field_should_be_last_tweet
assert_equal "last_tweet", Wickwall.yaffle_text_field
end
end
當您執行 bin/test
時,您應該看到以下內容:
# 跑步:
..E
Error:
ActsAsYaffleTest#test_a_wickwalls_yaffle_text_field_should_be_last_tweet:
NameError: uninitialized constant ActsAsYaffleTest::Wickwall
bin/test /path/to/yaffle/test/acts_as_yaffle_test.rb:8
E
Error:
ActsAsYaffleTest#test_a_hickwalls_yaffle_text_field_should_be_last_squawk:
NameError: uninitialized constant ActsAsYaffleTest::Hickwall
bin/test /path/to/yaffle/test/acts_as_yaffle_test.rb:4
Finished in 0.004812s, 831.2949 runs/s, 415.6475 assertions/s.
4 runs, 2 assertions, 0 failures, 2 errors, 0 skips
這告訴我們,我們沒有要測試的必要 models(Hickwall 和 Wickwall)。
我們可以通過從
test/dummy
目錄:
$ cd test/dummy
$ bin/rails generate model Hickwall last_squawk:string
$ bin/rails generate model Wickwall last_squawk:string last_tweet:string
現在您可以通過導航到您的虛擬應用程式在您的測試資料庫中建立必要的資料庫表 和遷移資料庫。首輪:
$ cd test/dummy
$ bin/rails db:migrate
當你在這裡時,改變 Hickwall 和 Wickwall models,讓他們知道他們應該採取行動 像yaffle。
# test/dummy/app/models/hickwall.rb
class Hickwall < ApplicationRecord
acts_as_yaffle
end
# test/dummy/app/models/wickwall.rb
class Wickwall < ApplicationRecord
acts_as_yaffle yaffle_text_field: :last_tweet
end
我們還將新增程式碼來定義 acts_as_yaffle
方法。
# yaffle/lib/yaffle/acts_as_yaffle.rb
module Yaffle
module ActsAsYaffle
extend ActiveSupport::Concern
class_methods do
def acts_as_yaffle(options = {})
end
end
end
end
# test/dummy/app/models/application_record.rb
class ApplicationRecord < ActiveRecord::Base
include Yaffle::ActsAsYaffle
self.abstract_class = true
end
然後您可以返回到外掛的根目錄 (cd ../..
) 並使用 bin/test
重新執行測試。
# 跑步:
.E
Error:
ActsAsYaffleTest#test_a_hickwalls_yaffle_text_field_should_be_last_squawk:
NoMethodError: undefined method `yaffle_text_field' for #<Class:0x0055974ebbe9d8>
bin/test /path/to/yaffle/test/acts_as_yaffle_test.rb:4
E
Error:
ActsAsYaffleTest#test_a_wickwalls_yaffle_text_field_should_be_last_tweet:
NoMethodError: undefined method `yaffle_text_field' for #<Class:0x0055974eb8cfc8>
bin/test /path/to/yaffle/test/acts_as_yaffle_test.rb:8
.
Finished in 0.008263s, 484.0999 runs/s, 242.0500 assertions/s.
4 runs, 2 assertions, 0 failures, 2 errors, 0 skips
越來越近了... 現在我們將實現 acts_as_yaffle
方法的程式碼以使測試通過。
# yaffle/lib/yaffle/acts_as_yaffle.rb
module Yaffle
module ActsAsYaffle
extend ActiveSupport::Concern
class_methods do
def acts_as_yaffle(options = {})
cattr_accessor :yaffle_text_field, default: (options[:yaffle_text_field] || :last_squawk).to_s
end
end
end
end
# test/dummy/app/models/application_record.rb
class ApplicationRecord < ActiveRecord::Base
include Yaffle::ActsAsYaffle
self.abstract_class = true
end
當您執行 bin/test
時,您應該看到測試全部通過:
4 runs, 4 assertions, 0 failures, 0 errors, 0 skips
4.2 新增實例方法
該外掛將向任何呼叫 acts_as_yaffle
的 Active Record 物件新增一個名為“squawk”的方法。 '吱吱'
方法將簡單地設定資料庫中欄位之一的 value。
首先,編寫一個失敗的測試來顯示您想要的行為:
# yaffle/test/acts_as_yaffle_test.rb
require "test_helper"
class ActsAsYaffleTest < ActiveSupport::TestCase
def test_a_hickwalls_yaffle_text_field_should_be_last_squawk
assert_equal "last_squawk", Hickwall.yaffle_text_field
end
def test_a_wickwalls_yaffle_text_field_should_be_last_tweet
assert_equal "last_tweet", Wickwall.yaffle_text_field
end
def test_hickwalls_squawk_should_populate_last_squawk
hickwall = Hickwall.new
hickwall.squawk("Hello World")
assert_equal "squawk! Hello World", hickwall.last_squawk
end
def test_wickwalls_squawk_should_populate_last_tweet
wickwall = Wickwall.new
wickwall.squawk("Hello World")
assert_equal "squawk! Hello World", wickwall.last_tweet
end
end
執行測試以確保最後兩個測試失敗並顯示包含“NoMethodError: undefined method `squawk'”的錯誤,
然後將 acts_as_yaffle.rb
更新為如下所示:
# yaffle/lib/yaffle/acts_as_yaffle.rb
module Yaffle
module ActsAsYaffle
extend ActiveSupport::Concern
included do
def squawk(string)
write_attribute(self.class.yaffle_text_field, string.to_squawk)
end
end
class_methods do
def acts_as_yaffle(options = {})
cattr_accessor :yaffle_text_field, default: (options[:yaffle_text_field] || :last_squawk).to_s
end
end
end
end
# test/dummy/app/models/application_record.rb
class ApplicationRecord < ActiveRecord::Base
include Yaffle::ActsAsYaffle
self.abstract_class = true
end
最後一次執行 bin/test
,您應該看到:
6 runs, 6 assertions, 0 failures, 0 errors, 0 skips
使用 write_attribute
寫入 model 中的欄位只是外掛如何與 model 互動的一個示例,並不總是正確的使用方法。例如,您還可以使用:
send("#{self.class.yaffle_text_field}=", string.to_squawk)
5 發電機
產生器可以包含在您的 gem 中,只需在外掛的 lib/generators
目錄中建立它們即可。有關的更多資訊
產生器的建立可以在產生器指南中找到。
6 釋出您的 Gem
當前正在開發的 Gem 外掛可以從任何 Git 儲存庫輕鬆共享。要與他人分享 Yaffle gem,只需
將程式碼提交到 Git 儲存庫(如 GitHub)並在相關應用程式的 Gemfile
中新增一行:
gem "yaffle", git: "https://github.com/rails/yaffle.git"
執行 bundle install
後,您的 gem 功能將可用於應用程式。
當 gem 準備好作為正式版本共享時,它可以釋出到 RubyGems。
或者,您可以從 Bundler 的 Rake 任務中受益。您可以檢視包含以下內容的完整列表:
$ bundle exec rake -T
$ bundle exec rake build
# 將 yaffle-0.1.0.gem 構建到 pkg 目錄中
$ bundle exec rake install
# 構建並安裝 yaffle-0.1.0.gem 到系統 gems
$ bundle exec rake release
# 建立標籤 v0.1.0 並構建並推送 yaffle-0.1.0.gem 到 Rubygems
有關將 gem 釋出到 RubyGems 的更多資訊,請參閱:釋出您的 gem。
7 RDoc 文件
一旦您的外掛穩定並且您準備好部署,請幫其他人一個忙併記錄下來!幸運的是,為您的外掛編寫文件很容易。
第一步是使用有關如何使用外掛的詳細資訊更新 README 檔案。一些 key 的內容包括:
- 你的名字
- 如何安裝
- 如何將功能新增到應用程式(常見用例的幾個示例)
- 可以幫助使用者並節省時間的警告、陷阱或提示
一旦你的自述檔案是可靠的,請仔細閱讀並向開發人員將使用的所有方法新增 rdoc 註釋。將 # :nodoc:
註釋新增到未包含在公共 API 中的程式碼部分也是一種習慣做法。
一旦你的評論好了,導航到你的外掛目錄並執行:
$ bundle exec rake rdoc
7.1 參考
回饋
我們鼓勵您幫助提高本指南的品質。
如果您發現任何拼寫錯誤或資訊錯誤,請提供回饋。 要開始回饋,您可以閱讀我們的 回饋 部分。
您還可能會發現不完整的內容或不是最新的內容。 請務必為 main 新增任何遺漏的文件。假設是 非穩定版指南(edge guides) 請先驗證問題是否已經在主分支上解決。 請前往 Ruby on Rails 指南寫作準則 查看寫作風格和慣例。
如果由於某種原因您發現要修復的內容但無法自行修補,請您 提出 issue。
關於 Ruby on Rails 的任何類型的討論歡迎提供任何文件至 rubyonrails-docs 討論區。