2009-03-31 19 views
8

Giả sử tôi có một ứng dụng đường ray với 3 kiểu máy, Person, Place and Thing. Giả sử Thing sử dụng kế thừa bảng đơn, vì vậy có các lớp con FancyThing và ScaryThing. Sau đó, có các tuyến đường được xác định với map.resources :people, :places, :things. Vì vậy, không có bộ điều khiển cho FancyThings và ScaryThings, các ThingsController xử lý một trong hai loại.Tìm tuyến đường cho lớp cơ sở của lớp STI trong Rails

Bây giờ, tôi cần có mã hiển thị danh sách mọi thứ có liên kết đến chúng. Nếu tôi có mã này trong quan điểm của tôi:

<% @items.each do |item| %> 
    <%= link_to item.name, item %> 
<% end %> 

Nếu mục là một người hoặc một Place, này hoạt động tốt, polymorphic_path chăm sóc tạo ra con đường đúng. Nhưng nếu mục là một FancyThing hoặc một ScaryThing, điều này thổi lên, bởi vì nó sẽ cố gắng sử dụng fancy_thing_path, mà không có tuyến đường cho. Tôi muốn bằng cách nào đó làm cho nó sử dụng thing_path. Lý tưởng nhất là sẽ có một phương thức trên Thing và/hoặc các lớp con của nó bằng cách nào đó cho thấy các lớp con nên sử dụng lớp cơ sở để tạo ra các tuyến đường. Có một giải pháp thanh lịch cho điều này?

+0

Đây là [vé mở] (http://dev.rubyonrails.org/ticket/10454) về phát triển đường ray. Xem vé cho các đề xuất về cách đối phó với nó. – MarkusQ

Trả lời

12

này sẽ làm các trick:

<% @items.map {|i| if i.class < Thing then i.becomes(Thing) else i end}.each do |item| %> 
    <%= link_to item.name, item %> 
<% end %> 

này sử dụng hàm ActiveRecord "trở thành" để làm một "up-cast" của tất cả các lớp con của Thing đến lớp cơ sở Thing.

+0

Tốt, tôi không biết về việc trở thành, cảm ơn! – pjb3

+0

Giải pháp này là khoảng 10x như thanh lịch như tôi đã mong đợi. –

8

Hãy thử sử dụng

map.resources :things 
map.resources :fancy_things, :controller => 'things' 
map.resources :scary_things, :controller => 'things' 
+1

+1 Vì hai lý do 1) Điều này phù hợp với tôi. 2) Câu trả lời này trông giống máy sấy hơn so với cái được chấp nhận bởi @ pjb3. Cảm ơn. – Rohit

+0

Giải pháp này có hiệu quả, nhưng có nhược điểm là nó không thực thi lớp/loại, ví dụ: nếu bạn truy vấn một id thông qua http: // localhost: 3000/fancy_things/21 và mục đó thực sự là từ một ScaryThings phụ lớp khác, bạn vẫn sẽ nhận được một phản hồi hợp lệ. Nó thực sự sẽ đưa ra một lỗi, bởi vì nó không phải là lớp FancyThings. – Tilo

0

Không có một câu trả lời chính xác, nhưng ít nhất tôi có thể đối phó với vấn đề này sử dụng mã phi DRY:

map.resources: sự vật,: has_many => : nhét map.resources: fancy_things,: controller => 'điều',: has_many =>: nhét map.resources: scary_things,: controller => 'điều',: has_many =>: nhét

Hy vọng vấn đề sẽ sớm được sửa chữa trong cạnh, vì tôi muốn xem fancy_things chỉ quản lý bởi: điều khiển mọi thứ. Sử dụng các đường bay, bạn sẽ kết thúc với các url như:/fancy_things/1 trong khi bạn có thể muốn/điều/1

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