2015-09-11 6 views
0

Я разработчик PHP и много работал с Laravel. Тем не менее, в настоящее время мне нужно сделать небольшое расширение для Redmine (Ruby Issue Tracker Tool) для работы.Rails: Расширение существующего кода

Я совершенно новый для Ruby и Rails, поэтому я одновременно стараюсь ускориться по языку и структуре.

В общем, мне нужно будет сделать некоторые миграции, которые добавят несколько столбцов в существующую таблицу Redmines. Затем, когда в Redmine запускаются различные методы (записи времени записи, удаление записей, создание проектов и т. Д.), Мне нужно сделать пару вызовов API и вставить/обновить возвращаемые данные в указанных столбцах.

Так что не очень сложно, но я задаюсь вопросом несколько вещей, как я получаю от земли:

1) Потому что я расширения существующего Rails приложение, я должен создавать плагин? или драгоценный камень? Кажется, Redmine имеет «плагин-генератор», который обеспечивает некоторую плиту котла

2) Мне нужно подключиться к существующим событиям «Сохранить и обновить» в Redmine. Насколько я понимаю, вы не должны переопределять существующие контроллеры и модели. В чем, какие методы используются для реализации дополнительных функций для существующего приложения?

Я нашел этот полезный кусок: 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. 

Предположительно, вы бы не добавлять методы непосредственно к первоисточнику? Я замечаю, что он использует Модули для реализации этого, но не знает точно, как они работают.

+1

Вы ищете плагины Redmine. Учебник доступен здесь: http://www.redmine.org/projects/redmine/wiki/Plugin_Tutorial – Nanego

ответ

1

Да, модификация первоначального источника не рекомендуется из-за:

  • Объединить проблемы, когда вы обновления Redmine
  • Проблемы с другими плагинами

Для добавления новых или модификации существующих методов Вы должны создать контроллер, модель или вспомогательный патч:

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

Смежные вопросы