Rails 3 - Вложенные ресурсы и полиморфные пути: нормально до двух уровней, но разбивается на три - PullRequest
9 голосов
/ 07 мая 2011

Я пытаюсь сделать простой сайт воссоединения семьи с: "сообщения", "семьи", "дети" и "фотографии".В идеале я хотел бы, чтобы маршруты / отношения были структурированы следующим образом:

  resources :posts do
    resources :pictures
  end

  resources :fams do
     resources :pictures
     resources :kids do
       resources :pictures
     end
  end

В моделях у меня есть необходимые отношения "belongs_to" и "has_many", установленные между fams и kids.Fams, kids и posts все определены с "has_many :pictures, :as => :imageable ", в то время как изображения определены как: belongs_to :imageable, :polymorphic => true

При попытке сделать link_to "Edit" и link_to "Destroy" в pictures views Я сталкиваюсь со всеми видами _path проблем. polymoric_path отлично работает на двух уровнях, а именно для posts-pictures и fams-pictures, но не может обработать трехуровневый случай fams-kids-pictures. Я предполагаю, чтоон не предназначен для обработки двух уровней объектов "imageable" над объектом picture. Другая проблема заключается в том, что в одном случае контроллер pictures должен обрабатывать ситуацию с вложением ресурсов одного уровня, а в другом -он должен справиться с ситуацией «двух уровней». Не знаю, как к этому подойти.

Одна вещь, которую я попытался сделать, это не вкладывать ресурсы больше, чем на одну глубину, в соответствии с указаниями Ruby Guides.:

  resources :posts do
    resources :pictures
  end

  resources :fams do
     resources :pictures
     resources :kids
  end

  resources :kids do
     resources :pictures
  end

Это вызвало еще один набор проблем с путями, поскольку отношения fam к kid больше не сохранялись. Я также не смог заставить polymorphic_path функционировать корректно во всех различных picture представлениях.

Итак, вот мой главный вопрос: кто-нибудь знает пример / учебник по Rails 3, где вложенные ресурсы, принадлежат / has_many и полиморфные отношения все вместе, особенно когда это не просто, два-уровневые отношения, которые показывают большинство примеров?(Я довольно новичок в Rails и Rails 2, примеры, которые я нашел в этих областях, сбивают с толку, учитывая мой недостаток исторического опыта Rails.)

Или кто-то может сказать мне, как структурировать link_to EDIT иОператоры link_to DELETE для моих picture представлений, а также операторы redirect-to для моих методов create, update и destroy в моем контроллере pictures?

Спасибо!

Ответы [ 3 ]

7 голосов
/ 21 июля 2011

Ваш пример кода, который ограничил ваше вложение 2 уровнями, очень близок к ответу. Чтобы избежать дублирования маршрутов для fams-> kids and kids, вы можете использовать опцию: only с пустым массивом, чтобы дети 1-го уровня не создавали маршруты, кроме как в контексте kids-> pictures, например:

resources :posts do
  resources :pictures
end

resources :fams do
  resources :pictures
  resources :kids
end

resources :kids, only: [] do # this will not generate kids routes
   resources :pictures
end

Для приведенного выше кода вы можете использовать следующее для создания своего полиморфного URL-адреса редактирования:

polymorphic_url([fam, picture], action: :edit) # using Ruby 1.9 hash syntax
polymorphic_url([kid, picture], action: :edit)
2 голосов
/ 20 июля 2011

У меня точно такая же проблема некоторое время. У меня сейчас работает, но не красиво: S

Из вложенного монстра вроде:

http://localhost:3000/destinations/3/accommodations/3/accommodation_facilities/52

Ваш params объект выглядит примерно так:

action: show
id: "52"
destination_id: "3"
accommodation_id: "3"
controller: accommodation_facilities

где "id" представляет идентификатор текущей модели (последний в цепочке), а остальные имеют идентификатор_модели_идейса

Чтобы правильно отобразить другую вложенную ссылку на этой странице, вам нужно передать массив объектов, составляющих полный путь, например, для ссылки на вымышленный объект FacilityType, который вам нужно сделать:

 <%= link_to "New", new_polymorphic_path([@destination, @accommodation, @accommodation_facility, :accommodation_facility_type]) %>

Чтобы сгенерировать этот массив из объекта params, я использую этот код в application_helper.rb

def find_parent_models(current_model = nil)
    parents = Array.new

    params.each do |name, value|
      if name =~ /(.+)_id$/
        parents.push $1.classify.constantize.find(value)
      end
    end

    parents.push current_model

    parents
end

Затем, чтобы автоматически сделать ту же ссылку, вы можете весело сделать:

 <%= link_to "New", new_polymorphic_path(find_parent_models(@accommodation_facility).push(:accommodation_facility_type)) %>

Любые указания о том, как сделать это решение менее схематичным, приветствуются:]

0 голосов
/ 07 мая 2011

Я не могу говорить о проблеме полиморфной ассоциации (вероятно, нужно больше информации о фактической ошибке), но вы действительно движетесь в правильном направлении, определяя вложенные ресурсы только на один уровень глубины. Вот популярная статья Джемиса Бака, которая стала справочной и которую вам, вероятно, стоит проверить.

...