2010-11-17 33 views
81

Tôi đã không thể tìm thấy giải pháp khả thi cho vấn đề này, mặc dù có một số câu hỏi tương tự ở đây và ở nơi khác. Có vẻ như câu hỏi này chưa được trả lời cho Rails 3, do đó, ở đây đi:Định tuyến đường ray để xử lý nhiều tên miền trên một ứng dụng đơn

Tôi có một ứng dụng hiện cho phép người dùng tạo tên miền phụ của riêng họ chứa phiên bản ứng dụng của họ. Trong khi ở Rails 2, bạn được phục vụ tốt nhất bằng cách sử dụng đá quý subdomain-fu, trong phiên bản 3 nó đơn giản hơn đáng kể, theo Railscast - http://railscasts.com/episodes/221-subdomains-in-rails-3.

Đó là nội dung hay, nhưng tôi cũng muốn cung cấp tùy chọn cho người dùng liên kết tên miền của riêng họ với tài khoản của họ. Vì vậy, trong khi họ có thể có http://userx.mydomain.com, tôi muốn họ chọn để có http://userx.com liên kết là tốt.

Tôi đã tìm thấy một vài tham chiếu để thực hiện việc này trong Rails 2, nhưng các kỹ thuật đó dường như không hoạt động nữa (đặc biệt là kỹ thuật này: http://feefighters.com/devblog/2009/01/21/hosting-multiple-domains-from-a-single-rails-app/).

Có ai có thể giới thiệu cách sử dụng các tuyến đường để chấp nhận miền tùy ý và chuyển nó sang bộ điều khiển để tôi có thể hiển thị nội dung phù hợp không?

Cập nhật: Tôi đã nhận được hầu hết câu trả lời ngay bây giờ, nhờ phản hồi kịp thời của Leonid và một cái nhìn mới về mã. Cuối cùng nó yêu cầu bổ sung cho mã Subdomain hiện tại mà tôi đang sử dụng (từ giải pháp Railscast) và sau đó thêm một chút vào routes.rb. Tôi không phải tất cả các cách có nhưng tôi muốn đăng những gì tôi có cho đến nay.

Trong lib/subdomain.rb:

class Subdomain 
    def self.matches?(request) 
    request.subdomain.present? && request.subdomain != "www" 
    end 
end 

class Domain 
    def self.matches?(request) 
    request.domain.present? && request.domain != "mydomain.com" 
    end 
end 

Tôi đã thêm lớp thứ hai trong sự bắt chước những người đầu tiên, được biết đến làm việc. Tôi chỉ cần thêm điều kiện để đảm bảo rằng miền đến không phải là miền tôi đang lưu trữ trang web chính.

Lớp này được sử dụng trong routes.rb:

require 'subdomain' 
constraints(Domain) do 
    match '/' => 'blogs#show' 
end 

constraints(Subdomain) do 
    match '/' => 'blogs#show' 
end 

Ở đây, tôi đang prepending mã subdomain hiện có (một lần nữa, nó làm việc tốt) với một câu kệ để kiểm tra sự Domain. Nếu máy chủ này phản hồi miền đó và không phải là máy chủ mà trang web chính hoạt động, hãy chuyển tiếp đến bộ điều khiển được chỉ định.

Và trong khi điều đó có vẻ đang hoạt động, tôi chưa hoàn toàn có toàn bộ công việc, nhưng tôi nghĩ rằng vấn đề cụ thể này đã được giải quyết.

+1

Cảm ơn bạn rất nhiều vì đã chỉnh sửa, Aaron. Tôi đang đối phó với chính xác tình hình tương tự ngay bây giờ. Như một câu hỏi tiếp theo, làm cách nào để máy chủ của bạn chấp nhận bất kỳ tên miền nào đang được chuyển tiếp tới nó? Tôi giả sử nó sẽ là một thiết lập trong tập tin .conf, nhưng tôi không chắc chắn những gì.Bất kỳ trợ giúp sẽ được đánh giá cao! – deadwards

+0

Aaron, tôi ở bên bạn. Tôi muốn làm điều tương tự. Nhưng tôi không muốn mã hóa tên miền. Tôi muốn tất cả được thực hiện theo chương trình mà không cần tệp vùng và máy chủ web khởi động lại. –

+1

Michael, bạn cần lật ngược vấn đề. Khai báo rõ ràng và mã hóa các tuyến đường dành riêng cho ứng dụng của bạn (ví dụ: đăng ký) với giới hạn máy chủ lưu trữ hoặc tên miền phụ, sau đó xử lý các tuyến đường chính của bạn là "bất kỳ tên miền hoặc tên miền phụ nào". Sau đó, trách nhiệm của bộ điều khiển của bạn là tra cứu tên miền hiện tại hoặc tên miền phụ và ánh xạ nó tới đúng khách hàng. –

Trả lời

88

Nó thực sự đơn giản trong Rails 3, theo http://guides.rubyonrails.org/routing.html#advanced-constraints:

1) xác định một lớp tùy chỉnh chế trong lib/domain_constraint.rb:

class DomainConstraint 
    def initialize(domain) 
    @domains = [domain].flatten 
    end 

    def matches?(request) 
    @domains.include? request.domain 
    end 
end 

2) sử dụng lớp trong tuyến đường của bạn với cú pháp khối mới

constraints DomainConstraint.new('mydomain.com') do 
    root :to => 'mydomain#index' 
end 

root :to => 'main#index' 

hoặc cú pháp tùy chọn kiểu cũ

root :to => 'mydomain#index', :constraints => DomainConstraint.new('mydomain.com') 
+0

Cảm ơn câu trả lời của bạn ... Tôi đã từ bỏ hy vọng! Nhưng nhìn vào mã này, có vẻ như tôi cần phải dự đoán tên miền đang được sử dụng. Tôi muốn sử dụng bất kỳ tên miền tùy ý nào. Nhưng bây giờ tôi đã phát hiện ra câu trả lời (chủ yếu), vì vậy tôi sẽ chỉnh sửa câu hỏi của mình ở trên. –

+0

Tại sao bạn khai báo lớp trong trình khởi tạo? Không nên có trong lib? – ybakos

+0

Đúng, nó phải ở dạng lib. –

Các vấn đề liên quan