2010-06-03 12 views
14

Bazı model ve kontrol cihazlarını tanımlayan bir motorum var. Uygulamamdaki bazı modellerin/denetleyicilerin işlevlerini (örn. Yöntemleri ekleme), motordan orijinal model/denetleyici işlevini kaybetmeden genişletmek istiyorum. Okuduğum her yerde, uygulamanızda aynı adı taşıyan denetleyiciyi tanımlamanız gerektiğine ve Rayların bunları otomatik olarak birleştireceğine inanıyorum, ancak benim için çalışmaz ve motordaki denetleyici basitçe göz ardı edilir (Hatta yüklendiğini sanmıyorum).Raylar motorları işlevselliğini artıyor

cevap

2

, bu motor tarafından sağlanan denetleyici devraldığı yeni denetleyicisi tanımlayamazsınız Bu, otomatik olarak dosya yolu 'uygulaması' ile başlıyorsa uygulamadan gerektiren önce motordan dosyaları gerektirecektir

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 

: benim sorunum sabit yazdım kodu.

+0

olup olmadıklarına bakılırsa, bu çözüm, kullanıcının Rails 3 için çalışmasıdır, bkz. Http://stackoverflow.com/questions/5045068/extending-controllers-of-a-rails-3-engine-in-the -main-app – Andrei

+0

Şimdi de Rails 3 için çalışıyor. – Andrei

+0

Bir yıl kadar önce bu cevaptan bir mücevher oluşturdum ama buraya göndermeyi unuttum. Bizim için iyi çalışıyor: https://github.com/EPI-USE-Labs/activesupport-decorators –

1

Bu doğrudur. İlk önce bulunan kontrolör kullanılacaktır. Yani

o iki seçeneğe sahip olabilir çalışması için:

  • Eğer eklenti üzerinde kontrol sahibi olmadığını
  • ihtiyaç yöntemi kontrolörü yerel bir kopyasını oluşturun ve değiştirmek, bir yaratabilecek Kodu içeren modül ve include her iki kontrolördeki kodu, sadece yerel kontrol cihazınızdaki yöntemi geçersiz kılar. Bana göre, birden fazla kalıtım olmadığından, tek yol budur. Bu yardımcı olur

Umut.

0

Daha önce Motorları hiç kullanmadım ama

herkesten aynı sorunla gelecekte bir kez çalışır Sadece eğer
+0

önce yüklenir sağlayacaktır. – Andrius

+0

Ayrı bir Ad alanı –

7

Sen lib kök dizininde size motorun modül dosyası şu satırları ekleyin: Ardından

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 

Eğer gerekli dosyaları gerektirecek ana uygulayabilme yeteneği (motorun uygulama yapma kullanımını) sahip motordan. Bu hoş bir şeydir çünkü Rails Engines'in varsayılan işlevselliğini korursunuz ve ayrıca, yamamaya gerek kalmadan normal yakut kalıtımını kullanmak için kolay bir araca sahip olursunuz.

EX: uygulamanızda modeli sınıf tanımı önce

#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" 
+0

MOTOR modelinden miras kalan MAIN APP Modeline kıyasla bu şekilde fayda sağlamanın yararı nedir? – westonplatter

+0

MAIN APP ve ENGINE APP modelinde bir model.rb dosyası varsa ancak ENGINE APP .rb, MAIN APP .rb'de gerekli değildir, Raylar ENGINE APP .rb'yi yoksayar. MAIN uygulamasına MOTOR, en azından bu cevabı yazdığım zaman, normal yakut kalıtımını takip etmemektedir. – joshmckin

+0

Bu çözümü beğendim! Sorum şu: eğer motordaki kullanıcı isim verdiyse? – user3281384

16
require MyEngine::Engine.root.join('app', 'models', 'my_engine', 'my_model') 

.

1

Modellerinizin her birinden kaçınmak için motorun yükleme sırasını değiştirebilirsiniz. konfigürasyonunda

/bu satırı ekleyin application.rb:

module MyApp 
    class Application 
    config.railties_order = [MyEngine::Engine, :main_app, :all] 
    end 
end 

Bu MyEngine gelen modeller aynı isme sahip değil ise Uygulamam

+0

Farkettiğim kadarıyla, Rails otomatik yükleme ilk tanımını (sizin durumunuzdaki motor modeli) bulur ve kullanır, aynı modelin olası diğer tanımlarını yüklemek için diğer yollardan geçmez. – linkyndy

İlgili konular