2009-10-21 27 views
9

Bağımsız hesap sitelerini ayırmak için alt alanlardan yararlanan bir Rails (şu an 2.3.4) uygulaması üzerinde çalışıyorum. Açık olmak gerekirse, foo.mysite.com 'un foo hesabı' içeriğini göstermesi ve bar.mysite.com 'un bar içeriğini göstermesi gerekir.Raylar: alt alana dayalı sorguları kapsamak için en iyi uygulama?

Tüm model sorgularının geçerli alt etki alanına ayrıldığından emin olmanın en iyi yolu nedir? Örneğin

, benim denetleyicileri biri gibi görünür:

@page = @global_organization.pages.find_by_id(params[:id])   

(@global_organization Not alt alan-fu aracılığıyla application_controller yer almaktadır.) ne tercih ediyorum olduğunda bir şey gibi:

@page = Page.find_by_id(params[:id]) 
Sayfa modelinin, doğru kuruluşa otomatik olarak eklendiği

. Böyle default_scope yönergesini kullanarak denedim: Küresel erişim için örgütün id: [organizasyonu] sadece nota, Yine

class Page < ActiveRecord::Base 
    default_scope :conditions => "organization_id = #{Thread.current[:organization]}" 
    # yadda yadda 
end 

((Sayfa modelinde), aynı application_controller Thread.current ayarlar.) Bu yaklaşımdaki sorun, varsayılan kapsamın ilk istek üzerine ayarlanması ve farklı alt alan adlarına yapılan sonraki taleplerde hiçbir zaman değişiklik olmamasıdır.

üç belirgin çözümler, şimdiye kadar:

1 kullanımlar ayrı her bir alt etki alanı için sankonlar ve sadece (mod_rails kullanılarak) alt alan başına uygulamanın farklı örneklerini çalıştırın. Bu yaklaşım, bu uygulama için ölçeklendirilemez.

2 Yukarıdaki orijinal denetleyici yaklaşımını kullanın. Ne yazık ki, uygulamada çok sayıda model bulunmaktadır ve modellerin çoğu, kuruluştan çıkarılmış birkaç bağlantıdır, bu yüzden bu gösterim hızlı bir şekilde zorlaşmaktadır. Daha da kötüsü, bu durumun geliştiricilerin sınırlamayı hatırlama ve uygulama ya da önemli bir güvenlik problemi riskini uygulamalarını gerektirmesidir.

3 Her istekte modellerin varsayılan kapsamını sıfırlamak için bir before_filter kullanın. Performansın ne kadar etkili olduğunu veya hangi modelin reqeust için güncelleneceğini en iyi nasıl seçeceğinizden emin değilsiniz.

Düşünceler? Eksik olduğum başka çözümler var mı? Bu, en iyi uygulama olması gereken ortak bir sorun gibi görünmektedir. Tüm girdiler takdir edildi, teşekkürler!

cevap

2

default_scope nu lambda tanımlamayı denediniz mi? Kapsamı her kullanışınızda değerlendirilen seçenekleri tanımlayan lambda bit.

class Page < ActiveRecord::Base 
    default_scope lambda do 
    {:conditions => "organization_id = #{Thread.current[:organization]}"} 
    end 
    # yadda yadda 
end 

Aslında senin önce filtre büyü ile tandem olarak çalışarak, üçüncü seçenek yapıyor. Ama bundan biraz daha agresif, Page modelinde kullanılan her bir bulmacayı tekmelemek.

Tüm modeller için bu davranışı istiyorsanız, default_scope'u ActiveRecord :: Base'e ekleyebilirdiniz, ancak birkaç tane daha katılmadan bahsedebilirsiniz. Bu nedenle bu rotaya giderseniz, bu modellerde birleştirmeleri ele almak için varsayılan kapsamları geçersiz kılmanız gerekir.

+0

teşekkürler! Bu kodu pratikte test ettin mi? Ben sadece uygulamada denedim ve lambda gerçekten her buluntu üzerinde değerlendirilmekte olduğunu teyit ederken, default_scope döndürülen değerleri uygulamıyor. SQL çıkışına bakıldığında, koşullar: basitçe göz ardı ediliyor gibi görünüyor. Diğer çeşitli nedenlerden dolayı hata ayıklayıcımı henüz başlatamadım, ancak geri dönüp çalışır vaziyette en yüksek seviyeye geleceğim. Neden çalışmadığına dair düşünceler var mı? – qfinder

+0

Dürüstçe İç sunucunun iş parçacığı nasıl kullandığı hakkında hiçbir fikrim yok, bu yüzden 'Thread.current [: organization]' modelinde çalıştım. Fakat bunun koşulların neden göz ardı edildiğini açıklayıp açıklamayacağını bilmiyorum. Esas olarak organazation_id = nil değerini aramak için varsayılan kapsamı tanımladığınızdan. – EmFi

+0

Daha fazla araştırma üzerine, bu henüz işe yaramıyor gibi görünüyor. Bir yama var, ama YMMV: https://rails.lighthouseapp.com/projects/8994/tickets/1812-default_scope-cant-take-procs – EmFi

2

Özellikle kayıt oluştururken sizi yanlış bir güvenlik hissine yönlendireceğinden, varsayılan kapsamı burada yapmaya dikkat edin.Ayrıca böylece yeni oluşturmak/eylemler bakacağız, yeni kayıtlar uygulanan bu ilişkiyi sağlamak istiyoruz çünkü

@page = @go.pages.find(params[:id]) 

en büyük nedeni:

Her zaman bu açık tutmak için ilk örneğini kullandım aşağıdaki gibi, düzgün Aile Birliğinin kapsamına sağlamaktan:

# New 
@page = @go.pages.new 

# Create 
@page = @go.pages.create(params[:page]) 
+0

İyi bir nokta, bu durumda, birleştirme yapısından ötürü, üzerinde yaratılması gereken sadece birkaç yer olduğu ortaya çıkıyor, ancak okumalarda zorlanması gereken birçok yer var, bu yüzden hala bir yol bulmak istiyorum. default_scope'u kullanmak için – qfinder

+0

Ayrıca, bir subdomain-scoped çok kiracı uygulaması ile başlamak için örnek bir uygulama olan http://github.com/devinterface/authlogic_subdomain_fu_startup_app bir göz atın. Hesap oluşturmayı ve ilk kullanıcıyı (aynı zamanda hesabın sahibi olan) yönetir. – bensie

+1

Denetleyicide ekstra iş/kod karmaşası gibi görünebilir, ancak gerçekten değil. Sonunda programcının niyetini gösterir, bu da yolu değiştirmek için çok daha kolay olacaktır. Geliştiricilerin sınırlamayı hatırlama ve uygulamalarına ihtiyaç duyduğunda, yine de her eylem için testlerinizin olması gerekir ve bu testlerden biri modelin ebeveynine doğru bir şekilde dağıtıldığından emin olmalıdır. – bensie

0

Sen alt etki dayalı bir database per account and switching the database connection sahip daha iyi olabilir.

Yukarıdaki bağlantıya ek olarak, varsayılan veritabanını kullanmak istediğiniz bir modeliniz (Hesabınızda) varsa, modele yalnızca establish connection ekleyin.

class Account < ActiveRecord::Base 

    # Always use shared database 
    establish_connection "shared_#{RAILS_ENV}".to_sym 
+0

Çalışılabilir bir çözüm olabilir, ancak hesaplar boyunca çalışan raporları (analitik) büyük bir acı haline getirir. Ayrıca göç, vb. –

+0

Evet, göçler benim için bir acı noktasıydı. Göçmenlerin bir veri tabanı listesiyle çalıştırılmasına izin veren bir çözüm görmeyi hatırlıyorum, ama nerede olduğunu hatırlayamıyorum. – Kris

İlgili konular