Создание пути редактирования для вложенного ресурса, на который ссылаются несколько моделей

В routes.rb:

resources :cars do
  resources :reviews
end

resources :motorcycles do
  resources :reviews
end

В ReviewsController:

before_filter :find_parent

def show
  @review = Review.find(params[:id])
  respond_to do |format|
    format.html # show.html.erb
    format.xml  { render :xml => @review }
  end
end

def edit
  @review = Review.find(params[:id])
end

# ...
def find_parent
  @parent = nil
  if params[:car_id]
    @parent = Car.find(params[:car_id])
  elsif params[:motorcycle_id]
    @parent = Motorcycle.find(params[:motorcycle_id])
  end
end

Создание ссылки "показать" для обзора просто (это работает):

= link_to "Show", [@parent, @review]

Аналогично, я хотел бы ссылаться на общий путь редактирования для обзора, что-то вроде (это не работает):

= link_to "Edit", [@parent, @review], :action => 'edit'

Кто-нибудь знает, возможно ли это или, если нет, как это может быть выполнено?

Ответ 1

Получается, что ответ, который я ищу, можно найти с помощью URL-адреса "edit_polymorphic_path" (см. http://rubydoc.info/github/rails/rails/master/ActionDispatch/Routing/PolymorphicRoutes). Чтобы получить ссылку, которую я пытаюсь сделать выше, я смог выполнить следующее:

edit_polymorphic_path([@parent, @review]) 

Ответ 2

link_to 'Edit Review', [:edit, @parent, @review]

Ответ 3

Я думаю, что здесь вам нужна полиморфная ассоциация. Райан Бейтс на Railscasts.com прекрасно объясняет это.

http://railscasts.com/episodes/154-polymorphic-association

Это облегчит вам такие вещи, как:

Пользователь, менеджер, заметка

Пользователь может иметь много заметок У менеджера может быть много заметок Примечание может принадлежать пользователю или менеджеру

пользователей/1/примечание/редактировать менеджеры/1/замечания/изменить

Railscast объяснит, как это сделать:)

EDIT:

def edit
  @reviewable= find_reviewable
  @reviews= @reviewable.reviews
end

private

def find_reviewable
  params.each do |name, value|
    if name =~ /(.+)_id$/
      return $1.classify.constantize.find(value)
    end
  end
  nil
end

Тогда в вашей ссылке это будет что-то вроде:

link_to 'Edit Review', edit_review_path([@reviewable, :reviews])

^^ Не тестировалось.