2009-08-11 31 views
7

Tôi không nhận được REST với Ruby on Rails, và tôi hy vọng một người nào đó ở đây có thể đặt tôi thẳng.Rails: làm thế nào để mô hình truy vấn RESTful thông qua các hiệp hội?

Hãy tưởng tượng rằng tôi đang tạo trang web theo dõi Tiện ích và Người dùng sở hữu những Widget đó. Vì vậy, tôi muốn có một UsersController và WidgetsController, và tôi có thể có được một danh sách các Widgets hoặc Người sử dụng với những hành động chỉ số:

GET /users 
GET /widgets 

và tôi có thể có được một tài khoản cụ thể hoặc Widget với những hành động cho thấy:

GET /users/id 
GET /widgets/id 

Tôi hiểu điều đó.

Tôi bị nhầm lẫn ở đâu là yêu cầu RESTful tôi sẽ sử dụng để truy xuất danh sách Tiện ích thuộc về một Người dùng cụ thể? Đó có phải là một yêu cầu được gửi đến UsersController hoặc WidgetsController không? Hành động nào trong số 7 hành động RESTful mà nó sử dụng?

Là một trong những tình huống mà tôi muốn tạo hành động tùy chỉnh? Tôi đã ấn tượng rằng hành động tùy chỉnh được cho là hiếm, nhưng điều này có vẻ như là một trường hợp sử dụng khá phổ biến.

Cảm ơn!

+0

Bạn thực sự nên nghe câu trả lời của Darrel Miller - Định dạng URI không liên quan gì đến REST. Bạn cũng nên xem xét một số chủ đề REST trên StackOverflow giải thích chi tiết hơn, hoặc xem xét luận án của Fielding. – aehlke

+1

Câu hỏi của tôi không phải về các URL đẹp - đó là về trình điều khiển Rails tôi sẽ sử dụng để xử lý yêu cầu và hành động nào sẽ được sử dụng. –

Trả lời

4

Url cho danh sách các vật dụng thuộc về một người dùng foo sẽ trông như thế này:

/users/foo/widgets 

Sau đó, bạn có thể lựa chọn cách thực hiện các URL của bạn cho mỗi của những widget. Điều này có thể:

/users/foo/widgets/bar 

Nhưng tôi thích điều này:

/widgets/bar 

tuyến đường của bạn sẽ trông như thế này:

map.resources :users, :has_many => :widgets, :shallow => true 
map.resources :widgets, :has_many => :users, :shallow => true 

(Đây là từ bộ nhớ, tôi có thể có hơi say lên một hoặc biết thêm chi tiết)

Phương pháp điều khiển xử lý /user/foo/widgetsindex hành động của WidgetController. Nó kiểm tra sự tồn tại của tham số user_id và hạn chế các tiện ích được trả về dựa trên đó. (Hoặc lấy người dùng foo và đặt @widgets để @user.widgets.)

Cập nhật: Có một cái nhìn tổng quan tốt của định tuyến lồng nhau mà trả lời câu hỏi ban đầu của tôi trong Rails Guides.

Cập nhật 2 Ồ vâng, tôi cũng muốn liên kết với một số documentation.

+0

Ah có ý nghĩa rất nhiều. Tôi không biết về tùy chọn: nông cho map.resources. Cảm ơn! –

+0

Phát hiện, nhưng mối quan hệ ở đây là "has_and_belongs_to_many" vì một người dùng có thể có nhiều tiện ích con và một tiện ích có thể thuộc về nhiều người dùng. – askegg

+0

Bạn có thể đã ghép nối has_many và has_many: thông qua các mối quan hệ với một cái gì đó giống như 'UserWidget' (tên lame) thay vì một' habtm' tôi đã nghĩ. – wombleton

1

Bạn đang tìm quá trình thiết kế khó khăn vì bạn đang cố gắng thiết kế trang web của mình dựa trên không gian URL khi bạn nên thiết kế tài liệu nội dung thay thế.

Dưới đây là tập hợp các loại phương tiện truyền thông sẽ giải quyết các yêu cầu của bạn.

Media Type: application/vnd.yourcompany.collections + xml

<Collections> 
    <Widgets href="http://yoursite.com/{9BCCD309-644C-4fb8-A35E-A8B5E6AC4AE8}"/> 
    <Users href="http://yoursite.com/{BE57DC2D-8FE7-45e3-9362-AF5F607D62B6}"/> 
</Collections> 

Media Type: application/vnd.yourcompany.Widgets + xml

<Widgets> 
    <Widget href="http://yoursite.com/{4A7B5583-5D09-4cf3-9781-1084977769C0}"/> 
    <Widget href="http://yoursite.com/{0D6A72E8-6088-462c-A97A-70BC43E25475}"/> 
</Widgets> 

Media Type: application/vnd.yourcompany Người dùng + xml

<Users> 
    <User href="http://yoursite.com/{6321D95E-7EDB-46b8-9430-AB57EA067B06}"/> 
    <User href="http://yoursite.com/{0D6A72E8-6088-462c-A97A-70BC43E25475}"/> 
</Users> 

Loại phương tiện: application/vnd.yourcompany.Widget + xml

<Widget> 
    <Property1>99</Property1> 
    <Property2>A Description</Property2> 
    <UsersOfWidget href="http://yoursite.com/{26995C10-CA1D-4f1f-9065-2246A8426DA7}"/> 
</Widget> 

Media Type: application/vnd.yourcompany.User + xml

<User> 
    <Name>Joe Smith</User> 
    <WidgetsOwnedByUser href="http://yoursite.com/{D718A2E6-6ADD-4d6e-A1E7-6DA68EDE0BD3}"/> 
</User> 

Rõ ràng này tập hợp các loại phương tiện truyền thông chỉ là một trong nhiều giải pháp tiềm năng cho vấn đề của bạn. Vấn đề tôi muốn thu hút sự chú ý của bạn là URL hầu như không liên quan. Làm thế nào các tài liệu liên quan đến nhau là quan trọng. Khi bạn nhìn vào nó theo cách này, không khó để phân biệt giữa các Widget được sử dụng bởi một người dùng và những người dùng sử dụng một Widget.

Bây giờ, cách bạn ánh xạ điều này với một bộ điều khiển Rails là một vấn đề khác. Vấn đề không phải là rất khó để thiết kế một giải pháp RESTful, nó chỉ là Rails dường như không bản đồ rất tự nhiên. Không phải là tôi có nhiều kinh nghiệm với Rails, vì vậy hãy coi đó là điều đáng giá. Tôi tin rằng bạn nên có một bộ điều khiển cho mỗi tài nguyên và thực tế là Rails cố gắng ép danh sách tài nguyên và tài nguyên chính nó vào một bộ điều khiển đơn là một sai lầm. Khách hàng và khách hàng là hai nguồn tài nguyên khác nhau theo ý kiến ​​của tôi.

Chỉnh sửa: Tập hợp các Url có thể có thể liên kết các tài nguyên này.

/Widgets 
/Users 
/Widget/1 
/User/99 
/Widget/1/UsersOfWidget 
/User/99/WidgetsOwned 

Tôi sẽ tạo bộ điều khiển cho từng điểm cuối này.

+1

Cảm ơn bạn đã trả lời, nhưng tôi đã có NFI những gì bạn đang nói về. Bạn thậm chí không có vẻ để đề cập đến Widgets thuộc sở hữu của người sử dụng? Tôi đang tìm kiếm một câu trả lời như "bạn nên tạo một hành động tùy chỉnh trên bộ điều khiển của bạn" hoặc "bạn nên sử dụng hành động chỉ mục trên bộ điều khiển Widgets của bạn và thực hiện XYZ trong đó". –

+0

:-) Tôi đã thay đổi tên của một số thành phần trong hai tài liệu cuối cùng để thử và làm rõ. Một quy ước mà tôi sử dụng trong các tài liệu XML được trả về từ các giao diện RESTful là nếu một phần tử có một href thì tôi có thể theo liên kết đó để lấy một đại diện đầy đủ của tài nguyên đó. Xin lỗi, tôi không nhận ra nó không rõ ràng. Tôi đoán tôi đã dành quá nhiều thời gian để xem các tài liệu như thế này. –

+1

Tôi biết bạn đang tìm kiếm "cách thức hoạt động trong Rails" nhưng những gì tôi đang cố gắng đạt được là suy nghĩ về URL và hành động trên bộ điều khiển sẽ khiến bạn khó thực hiện khi bạn nhấn mạnh hơn các vấn đề trong việc thiết kế giao diện RESTful. Tôi sẽ cho bạn thấy các URL mà tôi sẽ sử dụng để mô hình vấn đề này, từ đó nó có thể được rõ ràng làm thế nào để làm điều đó trong Rails. –

1

Tôi nghĩ Darrel đang cố gắng giáo dục bạn trên REST nói chung, như ông nói lo lắng quá nhiều về thiết kế URL có thể là dấu hiệu cho thấy bạn không thực sự thiết kế RESTfully. Ví dụ, như Darrel cho thấy, đại diện Người dùng của bạn có thể mang các liên kết đến các Widget mà anh ta/cô ta sở hữu (hoặc một liên kết đến một URL thực hiện tìm kiếm các widget đó do người dùng sở hữu).

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