Rails: неглубокое имя маршрута с настраиваемым поведением

Допустим, у меня есть две модели (Model1 и Model2), которые используют один и тот же контроллер, обе имеют много экземпляров Model3.

Как я могу вложить модель 3 в обе модели и иметь маршрут: modelmodel_2_model_3_path(@model)path(@model) вместо model_1_modelmodel_2_model_3_path(@model)path(@model) и model_2_model_3_path(@model)

Я хочу, чтобы моя функция model_3_path(@model) выглядела так:

def model_3_path(model)
  if model.is_a? Model1
    "/model1/#{model.id}/model3"
  elsif model.is_a? Model2
    "/model2/#{model.id}/model3"
  end
end

Мой текущий прогресс:

concern :three { resources :model3, shallow: true }
resources :model1, concerns: :three
resources :model2, concerns: :three, controller: :model1, except: [:index] # /model2 isn't permitted

Я не могу найти правильный подход...


person Danyel    schedule 26.06.2013    source источник


Ответы (2)


Я нашел простое решение: во-первых, я удалил shallow в model3. Открыв вспомогательный класс и добавив определение method_missing, это было легко возможно:

def method_missing(method, *args, &block)
  super unless /model3s?_(path|url|uri)$/ =~ method.to_s
  sub_string = nil
  if args.first.is_a? Model1
    substring = 'model1'
  elsif args.first.is_a? Model2
    substring = 'model2'
  end
  self.send(method.to_s.gsub('model3', "#{substring}_model3"), *args, &block)
end

Можно было бы определить каждый из них отдельно (new_model3_path, model3_path, edit_model3_path, model3s_path), но я нашел этот более кратким.

person Danyel    schedule 27.06.2013

Если вы хотите иметь путь, который не указывает его родителя, просто укажите его как маршрут верхнего уровня, а не проблему.

person MatthewFord    schedule 26.06.2013
comment
Я хочу, чтобы они указали своих родителей, я только хочу, чтобы именованный маршрут был общим, в зависимости от входящего параметра, который может быть либо Model1, либо Model2. Пожалуйста, прочитайте вопрос внимательнее. - person Danyel; 27.06.2013