Tôi có một công cụ xác định một số mô hình và bộ điều khiển. Tôi muốn để có thể mở rộng chức năng của một số mô hình/bộ điều khiển trong ứng dụng của tôi (ví dụ như thêm phương pháp) mà không mất chức năng mô hình/điều khiển ban đầu từ động cơ. Ở khắp mọi nơi tôi đọc rằng bạn chỉ cần xác định bộ điều khiển có cùng tên trong ứng dụng của bạn và Rails sẽ tự động hợp nhất chúng, tuy nhiên nó không hoạt động đối với tôi và bộ điều khiển trong công cụ chỉ đơn giản là bỏ qua (Tôi không nghĩ rằng nó thậm chí được nạp).Rails động cơ mở rộng chức năng
Trả lời
Chỉ cần nếu bất cứ ai khác chạy vào cùng một vấn đề một số thời gian trong tương lai, đây là mã tôi đã viết khắc phục sự cố của tôi:
module ActiveSupport::Dependencies
alias_method :require_or_load_without_multiple, :require_or_load
def require_or_load(file_name, const_path = nil)
if file_name.starts_with?(RAILS_ROOT + '/app')
relative_name = file_name.gsub(RAILS_ROOT, '')
@engine_paths ||= Rails::Initializer.new(Rails.configuration).plugin_loader.engines.collect {|plugin| plugin.directory }
@engine_paths.each do |path|
engine_file = File.join(path, relative_name)
require_or_load_without_multiple(engine_file, const_path) if File.file?(engine_file)
end
end
require_or_load_without_multiple(file_name, const_path)
end
end
Điều này sẽ tự động yêu cầu tệp từ động cơ trước khi yêu cầu từ ứng dụng nếu đường dẫn tệp bắt đầu bằng 'ứng dụng'.
Điều đó đúng. Bộ điều khiển được tìm thấy đầu tiên sẽ được sử dụng.
Vì vậy, để làm cho nó hoạt bạn có thể có hai lựa chọn:
- tạo ra một bản sao cục bộ của bộ điều khiển, và sửa đổi các phương pháp bạn cần
- nếu bạn có quyền kiểm soát các plugin, bạn có thể tạo một Module chứa mã và include mã trong cả hai bộ điều khiển, chỉ ghi đè phương thức trong bộ điều khiển cục bộ của bạn. Theo tôi, vì không có nhiều thừa kế, đó là cách duy nhất.
Hy vọng điều này sẽ hữu ích.
Tôi chưa bao giờ sử dụng động cơ trước nhưng bạn không thể xác định một bộ điều khiển mới được thừa kế từ bộ điều khiển được cung cấp bởi động cơ
Không nếu họ có cùng tên. – Andrius
Điều gì sẽ xảy ra nếu chúng ở một không gian riêng biệt –
Bạn có thể thêm những dòng này cho bạn tập tin mô-đun của động cơ trong thư mục gốc lib:
def self.root
File.expand_path(File.dirname(File.dirname(__FILE__)))
end
def self.models_dir
"#{root}/app/models"
end
def self.controllers_dir
"#{root}/app/controllers"
end
Sau đó, bạn có khả năng trong việc áp dụng chính (làm cho ứng dụng sử dụng động cơ) để yêu cầu các tập tin cần thiết từ động cơ. Điều này là tốt đẹp bởi vì bạn duy trì Rails Engines chức năng mặc định và cũng có một công cụ dễ dàng để làm cho việc sử dụng thừa kế ruby bình thường, mà không cần phải vá.
EX:
#ENGINE Model -
class User < ActiveRecord::Base
def testing_engine
puts "Engine Method"
end
end
#MAIN APP Model -
require "#{MyEngine.models_dir}/user"
class User
def testing_main_app
puts "Main App Method"
end
end
#From the Main apps console
user = User.new
puts user.testing_engine #=> "Engine Method"
puts user.tesing_main_app #=> "Main App Method"
lợi ích của việc làm theo cách này so với Mô hình APP CHÍNH kế thừa từ mô hình ENGINE? – westonplatter
Nếu tệp model.rb có trong MAIN APP và APP ENGINE nhưng APP ENGINE .rb không được yêu cầu trong APP CHÍNH .rb, Rails bỏ qua ENGINE APP .rb. ENGINE để MAIN ứng dụng không theo di sản ruby bình thường, ít nhất là khi tôi đã viết câu trả lời này. – joshmckin
Tôi thích giải pháp này! Câu hỏi của tôi là: nếu Người dùng trong công cụ trong không gian tên thì sao? – user3281384
require MyEngine::Engine.root.join('app', 'models', 'my_engine', 'my_model')
trước khi định nghĩa lớp mô hình trong ứng dụng của bạn.
Bạn có thể thay đổi thứ tự tải của động cơ để tránh yêu cầu trên từng kiểu máy của bạn.
Trong config/application.rb thêm dòng này:
module MyApp
class Application
config.railties_order = [MyEngine::Engine, :main_app, :all]
end
end
Điều này sẽ đảm bảo rằng các mô hình từ MyEngine được nạp trước khi MyApp
Theo như tôi biết, Rails tự động tải tìm định nghĩa đầu tiên (mô hình động cơ trong trường hợp của bạn) và sử dụng nó, nó không đi qua các đường dẫn khác để tải các định nghĩa có thể khác của cùng một mô hình. – linkyndy
- 1. Mở rộng h: outputText cho chức năng tùy chỉnh
- 2. C Macro mở rộng thành nhiều chức năng gọi
- 3. Clojure: Pass 'mở rộng' tùy chọn args để chức năng
- 4. Delphi 2010 Chức năng rộng so với chức năng chuỗi
- 5. Làm thế nào để mở rộng lớp BaseDaoImpl của ORMLite trên Android để mở rộng chức năng
- 6. Cython biên dịch C mở rộng: ImportError: mô-đun năng động không xác định chức năng init
- 7. Khả năng mở rộng DotNetNuke
- 8. Khả năng mở rộng MSMQ
- 9. Lớp động mở rộng
- 10. Liên hệ chức năng trong Rails 3
- 11. chức năng mở và fopen
- 12. Chức năng tự động AJAX
- 13. Danh sách động tự động mở rộng
- 14. Tổ chức các phương pháp mở rộng
- 15. Khả năng mở rộng là Cầu cảng?
- 16. Mở rộng việc tạo đơn lẻ với chức năng tùy chỉnh tùy chỉnh onclick
- 17. java mở rộng hoặc bọc một lớp để thêm chức năng bổ sung
- 18. Chức năng động docstring
- 19. Rails Chỉ số chức năng Postgres
- 20. Rails - Chức năng toàn cầu phổ quát
- 21. Chức năng gọi trên cửa sổ mở
- 22. Mẹo CEDET khả năng mở rộng
- 23. Khả năng mở rộng dịch vụ Azure
- 24. Scala gạch dưới - ERROR: thiếu kiểu tham số cho chức năng mở rộng
- 25. "Thiếu loại tham số cho chức năng mở rộng" khi sử dụng _ (gạch dưới)?
- 26. Chức năng cơ bản trong unityscript
- 27. Kiểm tra chức năng ủy quyền trong Rails
- 28. Rails 3.2 Bố cục động cơ
- 29. Có thể gọi chức năng mở rộng Java từ Xalan trên Android không?
- 30. Mở chức năng của mảng lồng nhau
Công việc của giải pháp này doen cho Rails 3, hãy xem http://stackoverflow.com/questions/5045068/extending-controllers-of-a-rails-3-engine-in-the -main-app – Andrei
Bây giờ nó cũng hoạt động cho Rails 3. – Andrei
Tôi tạo ra một viên ngọc từ câu trả lời này khoảng một năm trước nhưng quên đăng nó ở đây. Nó hoạt động tốt cho chúng tôi: https://github.com/EPI-USE-Labs/activesupport-decorators –