可以将自定义路径附加到Rails路由的“新”路径吗?

时间:2009-10-02 10:53:44

标签: ruby-on-rails ruby routes

我正在尝试做什么:

我正在构建一个系统,其中有不同类型的帖子。抛开模型,这个问题是关于路线和控制器

基本上/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确实将我发送到正确的页面来创建一个quip,等等。 /posts/new会将我发送到索引页面。

问题是双重的。

  1. 我仍然希望有这样的便利方法:

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

    但现在这已无效,因为new_post_path需要:type参数。

  2. 我想尽可能使用一条路线。

3 个答案:

答案 0 :(得分:3)

Peter Wagenet的解决方案给了我一个难题(: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'

答案 1 :(得分:2)

如果您可以分享行动,那么您可以设置以下内容:

# 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

答案 2 :(得分:0)

我认为你应该看看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数组自动给出类型。