Можно ли добавить собственный путь к «новому» пути для маршрутов Rails? - PullRequest
1 голос
/ 02 октября 2009

Что я пытаюсь сделать:

Я строю систему, в которой есть разные типы постов. Если оставить в стороне модели, этот вопрос о маршрутах и ​​контроллере

В основном /posts/new должен идти на какую-то страницу индекса, в то время как /posts/new/anything должен искать тип anything и затем создавать форму для создания новой.

Как я пытаюсь это сделать:

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

В конфиге маршрутов:

map.connect '/posts/new', :controller => 'posts', :action => 'new_index'
map.resources :posts, :path_names => { :new => 'new/:type' }

В контроллере:

class PostsController
  # implicit: def new_index ; end

  def new
    @post = class_for_type(params[:type]).new
  end
end

Представление имеет код, который смотрит на тип @post, чтобы определить, какой набор представлений использовать. Оказывается, это дает мне 90% пути: /posts/new/quip на самом деле отправляет меня на правильную страницу, чтобы создать шутку и так далее. /posts/new отправляет меня на главную страницу.

Проблема двоякая.

  1. Я все еще хочу использовать такие удобные методы:

    <%= link_to 'New Post', new_post_path %>
    

    Но теперь это недопустимо, поскольку new_post_path требует параметр :type.

  2. Я хотел бы сделать это, используя один маршрут, если это возможно.

Ответы [ 3 ]

3 голосов
/ 03 октября 2009

Решение Питера Вагенета дало мне недостающий фрагмент головоломки (:type => nil), что позволяет мне сделать это в одной строке:

map.resources :posts, :path_names => { :new => 'new/:type' },
              :requirements => { :type => nil }

Конечно, мне все равно пришлось зайти в контроллер и исправить его, чтобы он отображал new_index.html.erb из действия :new.

(Ну, я думаю, это больше не одна строка.)

new_post_path                     # => '/posts/new/'
new_post_path(:type => 'quip')    # => '/posts/new/quip'
new_post_path('quip')             # => '/posts/new/quip'
2 голосов
/ 04 октября 2009

Если вы можете жить с разделением действий, то вы можете настроить следующее:

# Routes
map.new_person '/people/new/:type', :controller => :people, :action => :new, :type => nil
map.resources :people, :except => [:new]

# Controller
class PeopleController < ApplicationController

  def new
    unless params[:type]
      render :action => :new_index and return
    end

    @post = class_for_type(params[:type]).new
  end

end

Это позволяет вам сохранить один маршрут в формате по умолчанию, а также возможность указывать типы:

new_person_path                      # => /people/new/
new_person_path(:type => 'anything') # => /people/new/anything
new_person_path(:employee)           # => /people/new/employee
0 голосов
/ 02 октября 2009

Думаю, вам стоит взглянуть на наследование таблиц в rails: http://juixe.com/techknow/index.php/2006/06/03/rails-single-table-inheritance/

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

Для самой проблемы, почему бы просто не переопределить вспомогательный метод new_post_path? Что-то вроде:

def new_post_path
    { :controller => 'posts', :action => 'new', :type => params[:type] }
end

Тип теперь автоматически задается на основе массива params.

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