Rails: как RESTful модели запросов через ассоциации? - PullRequest
7 голосов
/ 11 августа 2009

Я не получаю REST с Ruby on Rails, и я надеюсь, что кто-то здесь может поправить меня.

Представьте, что я создаю сайт, который отслеживает виджеты и пользователей, которым принадлежат эти виджеты. Таким образом, у меня был бы UsersController и WidgetsController, и я мог бы получить список Widgets или Users с действиями индекса:

GET /users
GET /widgets

и я могу получить конкретного пользователя или виджет с действиями шоу:

GET /users/id
GET /widgets/id

Это я так понимаю.

Где я запутался, какой запрос RESTful я бы использовал, чтобы получить список виджетов, принадлежащих конкретному пользователю? Это запрос отправлен в UsersController или WidgetsController? Какие из 7 действий RESTful он использует?

Является ли одна из тех ситуаций, в которой я бы создал настраиваемое действие? У меня сложилось впечатление, что пользовательские действия должны быть редкими, но это похоже на довольно распространенный вариант использования.

Спасибо!

Ответы [ 3 ]

4 голосов
/ 11 августа 2009

URL-адрес для списка виджетов, принадлежащих пользователю foo будет выглядеть следующим образом:

/users/foo/widgets

Затем у вас есть выбор, как сделать ваши URL для каждого из этих виджетов. Это возможно:

/users/foo/widgets/bar

Но я предпочитаю это:

/widgets/bar

Ваши маршруты будут выглядеть так:

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

(Это из памяти, возможно, я испортил одну или несколько деталей)

Метод контроллера, который обрабатывает /user/foo/widgets, является действием index WidgetController. Он проверяет наличие параметра user_id и ограничивает возвращаемые виджеты, основываясь на этом. (Или получает пользователя foo и устанавливает @widgets в @user.widgets.)

Обновление: Существует хороший обзор вложенной маршрутизации, который отвечает на мой оригинальный вопрос в Rails Guides .

Обновление 2 О да, я имел в виду ссылку на некоторую документацию .

1 голос
/ 11 августа 2009

Я думаю, что Даррел пытается рассказать вам о REST в целом, поскольку он говорит, что слишком большое беспокойство по поводу дизайна URL-адресов может быть признаком того, что вы на самом деле не разрабатываете RESTful. Например, как показывает Даррел, ваше представление пользователя может содержать ссылки на принадлежащие ему виджеты (или ссылку на URL, который выполняет поиск этих виджетов, принадлежащих пользователю).

1 голос
/ 11 августа 2009

Вы находите процесс разработки сложным, потому что вы пытаетесь создать свой сайт на основе пространства URL-адресов, когда вместо этого вы должны разрабатывать свои контентные документы.

Вот скелетный набор типов носителей, которые будут соответствовать вашим требованиям.

Тип носителя: 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>

Тип мультимедиа: 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>

Тип носителя: application / vnd.yourcompany.Users + xml

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

Тип носителя: application / vnd.yourcompany.Widget + xml

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

Тип носителя: application / vnd.yourcompany.User + xml

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

Очевидно, этот набор типов носителей является лишь одним из многих возможных решений вашей проблемы. Проблема, на которую я хочу обратить ваше внимание, заключается в том, что URL-адрес в значительной степени не имеет значения. Как документы взаимосвязаны, важно. Когда вы смотрите на это таким образом, нетрудно различить виджеты, используемые Пользователем, и Пользователей, которые используют Виджет.

Теперь, как вы сопоставляете это с набором контроллеров Rails, это совсем другое дело. Проблема не в том, что сложно разработать решение RESTful, просто в Rails, кажется, нет естественного отображения. Не то чтобы у меня был большой опыт работы с Rails, так что принимайте это за то, что оно того стоит. Я считаю, что у вас должен быть один контроллер на ресурс, и тот факт, что Rails пытается сжать список ресурса и самого ресурса в один контроллер, является ошибкой. Клиенты и Клиент - это, на мой взгляд, два разных ресурса.

Редактировать: Возможный набор URL, которые могут связывать эти ресурсы.

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

Я бы создал контроллер для каждой из этих конечных точек.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...