[英]Rails: Extending existing code
我是一名PHP開發人員,並且與Laravel進行了廣泛的合作。 但是,我目前需要對Redmine(Ruby問題跟蹤工具)進行小擴展才能工作。
我是Ruby和Rails的新手,所以我同時嘗試加快語言和框架的速度。
通常,我需要進行一些遷移,從而向Redmines現有表中添加幾列。 然后,當在Redmine中觸發各種方法(記錄時間條目,刪除條目,創建項目等)時,我將需要進行幾次API調用,並在所述列中插入/更新返回的數據。
所以並不是很復雜,但是我想知道起步時的一些事情:
1)因為我要擴展現有的Rails應用程序,所以我應該創建一個插件嗎? 還是寶石? 看來Redmine有一個“插件生成器”,可以提供一些樣板
2)我需要了解Redmine中現有的Save和Update事件。 據我了解,您並不是要覆蓋現有的Controllers和Models。 那樣,使用什么方法為現有應用程序實現附加功能?
我發現這很有幫助: http : //www.redmine.org/projects/redmine/wiki/Plugin_Internals
但是,它提到:
As explained above: you rarely want to override a model/controller. Instead you should either:
1) add new methods to a model/controller or
2) wrap an existing method.
想必您不會將方法直接添加到原始源嗎? 我注意到他使用模塊來實現此目的,但是不確定它們的工作方式。
是的,由於以下原因,不建議對原始源進行修改:
若要添加新方法或修改現有方法,必須創建控制器,模型或幫助程序補丁程序:
require_dependency 'issues_controller'
module IssuesControllerPatch
def self.included(base) # :nodoc:
base.send(:include, InstanceMethods)
base.class_eval do
unloadable
alias_method_chain :some_method, :your_action # modify some_method method by adding your_action action
end
module InstanceMethods
# modified some_method
# You can call original method before or after
# even in the middle of your actions
# or not to call to all
def some_method_with_your_action # modified some_method
do_something_before # your actions before
some_method_with_your_action # call original some_method if needed
do_something_after # your actions after
end
# new method
def your_method
do_something
end
end
end
IssuesController.send :include, IssuesControllerPatch
並添加
require 'path/to/your/issues_controller_patch'
到your_plugin/init.rb
另外,如果要在原始代碼中間調用代碼,則必須使用鈎子。 在原始代碼(控制器,視圖,幫助器,模型)中找到nessecary鈎子,它們看起來像這樣:
call_hook(:controller_account_success_authentication_after, {:user => user})
如果找不到合適的鈎子,則可以添加自己的鈎子(仍然需要修改原始代碼)或在Redmine頁面中添加問題(將需要等待很長時間)
要使用鈎子,請添加鈎子偵聽器,例如:
class IssuesControllerHookListener < Redmine::Hook::ViewListener
# use view hook - add path/to/your/view.html.erb redmine issues list
# position of your additions depends of used hook position
# view_issues_index_bottom is hook name
# :partial is parameter, value of that is your view
render_on :view_issues_index_bottom, :partial => 'path/to/your/view'
# use controller hook - call your code inside original
# controller_issues_ready_before_index is hook name, method must be named same
# context here is parameters come from hook calling method
# You can use it for your own purposes
def controller_issues_ready_before_index(context = {})
if context[:some_context_param] == some_value
do_something
end
end
end
並添加
require 'path/to/your/hook'
到your_plugin/init.rb
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.