わかりました。ホスト アプリの application_controller.rb を変更するのは適切ではないことに同意します。gem を介して ApplicationController クラス (実際には ActionController::Base) にメソッドを追加するさまざまな方法を見てみましょう。
非常にシンプルな宝石を作成しました。rot13 という 1 つの関数を追加したいのですが、これは、どのコントローラーでもrot13('something!')
get backを呼び出すことができることを意味します'fbzrguvat!'
。(実際には、これをString
... に追加します)
ActionController::Base
次のように拡張できます。
class ActionController::Base
def rot13 str
a = 'a'.ord
z = 'z'.ord
str.unpack('c*').map { |x| (a..z).cover?(x) ? (((x - a) + 13) % 26) + a : x }.pack('c*')
end
end
そして今、私のアプリケーションでは、rot13('ibvyn!')
任意のコントローラー内で呼び出すことができ、voila!
モジュールを追加し、Railtie フックを介して ActionController::Base に含める方が安全です。それでは、Railtie を追加しましょう。
次のように追加lib/rot13/railtie.rb
します。
module Rot13
class Rot13Railtie < Rails::Railtie
initializer "rot_13_railtie.extend_action_controller" do
ActiveSupport.on_load :action_controller do
# At this point, self == ActionController::Base
include Rot13::ControllerMethods
end
end
end
end
lib/rot13.rb
次のようになります。
require "rot13/version"
require "rot13/railtie.rb" if defined? Rails
module Rot13
module ControllerMethods
def rot13 str
a = 'a'.ord
z = 'z'.ord
str.unpack('c*').map { |x| (a..z).cover?(x) ? (((x - a) + 13) % 26) + a : x }.pack('c*')
end
end
end
ほとんどの場合、これで問題ありません。
rot13
メソッドを定義してすべてのコントローラーで使用できるようにしたくないとしましょう。たとえばActionController::Base
、gem のユーザーにコントローラーごとに「オプトイン」してもらいたいとしましょう。
class ApplicationController < ActionController::Base
with_rot_13
# and so on...
end
そのブロック内で をinclude Rot13::ControllerMethods
呼び出して のクラス レベルでメソッドを追加する代わりに、次のようにモジュールを定義します。extend Rot13::ControllerOptIn
on_load
with_rot_13
ActionController::Base
ControllerOptIn
module Rot13
module ControllerMethods
# ...
end
module ControllerOptIn
def with_rot_13
include ControllerMethods
end
end
end
それでおしまい!
編集:「なぜメソッドがビューに表示されないのですか?」という追加の質問に対処するためだけに--メソッドはヘルパーとして定義されていないため、接尾辞を付けないとビューに自動的に表示されませcontroller
ん%p= controller.rot13 'blah'
。helper_method
幸いなことに、への呼び出しを使用してヘルパーとして定義できます。
module ControllerOptIn
def with_rot_13
include ControllerMethods
helper_method :rot13
end
end
これを行うことができます (注: HAML):
%p= controller.rot13 'hello there!'
%p= rot13 'well how are ya?'
しかし、ここで指定する必要があるのは素晴らしいことではありませんhelper_method :rot13
。必要な記号を からまっすぐ掘り出せますRot13::ControllerMethods
か? もちろん、それがあなたが望むものであると確信している限り:
module ControllerOptIn
def with_rot_13
include ControllerMethods
helper_method *ControllerMethods.instance_methods
end
end