【问题标题】:Namespace routing rails nightmare命名空间路由的噩梦
【发布时间】:2011-03-20 11:16:58
【问题描述】:

我仍在学习 Rails 3,但路线让我发疯。我正在尝试使用命名空间来分隔站点的管理部分。问题是命名空间中的某些东西根本不起作用,并且还会路由到错误的位置。例如,通过指定资源来使用 rails 生成的路线,当传递一个对象时,视图指向错误的路线,因此编辑表单将不起作用。

即使路由确实存在,带有 link_to 的链接也不起作用,它说它不存在。首先是 rake 路由输出的命名空间路由。

namespace :admin do
  resources :users
end


admin_users GET        /admin/users(.:format)          {:action=>"index", :controller=>"admin/users"}
                POST   /admin/users(.:format)          {:action=>"create", :controller=>"admin/users"}
 new_admin_user GET    /admin/users/new(.:format)      {:action=>"new", :controller=>"admin/users"}
edit_admin_user GET    /admin/users/:id/edit(.:format) {:action=>"edit", :controller=>"admin/users"}
     admin_user PUT    /admin/users/:id(.:format)      {:action=>"update", :controller=>"admin/users"}
                DELETE /admin/users/:id(.:format)      {:action=>"destroy", :controller=>"admin/users"}

控制器:

class Admin::UsersController < ApplicationController

  def index
    @users = User.all
  end

  def show
    @user = User.find(params[:id])
  end

  def new
    @user = User.new
  end

  def edit
    @user = User.find(params[:id])
  end

  def create
    @user = User.new(params[:user])
    if @user.save
      redirect_to(@user, :notice => 'User was successfully created.')
    else
      render :action => "new"
    end
  end

  def update
    @user = User.find(params[:id])
    if @user.update_attributes(params[:user])
      redirect_to(admin_users_path, :notice => 'User was successfully updated.')
    else
      render :action => "edit"
    end
  end

  def destroy
    @user = User.find(params[:id])
    @user.destroy
    redirect_to(admin_users_path)
  end
end

示例视图:index.html.erb 列出所有用户

<h1>Listing users</h1>

<table>
<% for user in @users %>
  <tr>
    <td><%= user.id %></td>
    <td><%= user.username %></td>
    <td><%= user.email %></td>
    <td><%= link_to 'Show', @user %></td>
    <td><%= link_to 'Edit', edit_admin_user_path(user) %></td>
    <td><%= link_to 'Destroy', admin_user_path, :confirm => 'Are you sure?', :method => :delete %></td>
  </tr>
<% end %>
</table>

<br />

<%= link_to 'New User',  new_admin_user_path %>

使用编辑视图也有问题。编辑表单应该指向更新路线,但没有。相反,它仅在传递一个用户对象时指向编辑路由(基本上是它自己)。从我一直在阅读的内容来看,在表单中使用对象是推荐的方式,但如果它不起作用,这将不是一件好事。

我在列出所有用户页面时收到此错误。

No route matches {:action=>"update", :controller=>"admin/users"}

Extracted source (around line #17):
17:     <td><%= link_to 'Destroy', admin_user_path, :confirm => 'Are you sure?', :method => :delete %></td>

我非常努力地坚持,但这让我发疯。仅供参考:是的,我知道那里有身份验证框架,但我正在尝试从头开始制作一个。这是一种学习体验,因此在我看来,随便使用 gems 和插件并不是正确的选择。

谢谢 八分之一

【问题讨论】:

    标签: ruby-on-rails ruby routes


    【解决方案1】:

    您在删除链接中缺少 id

    试试

    <td><%= link_to 'Destroy', admin_user_path(user), :confirm => 'Are you sure?', :method => :delete %></td>
    

    (将 admin_user_path 更改为 admin_user_path(user) 作为链接)

    【讨论】:

    • 这很有效,谢谢,但表单仍然存在问题。 制作
      但应该制作 /admin/users/1 并使用更新方法。如果我在表单标签中使用@user,它只会抛出没有 user_path
    • 试试&lt;%= form_for [:admin, @user] do %&gt;
    • 奇怪的是,rails 脚手架无法正确处理命名空间。
    【解决方案2】:

    如果您执行 rake routes,您会看到如下内容:

        admin_users GET    /admin/users(.:format)            {:controller=>"admin/users", :action=>"index"}
                          POST   /admin/users(.:format)            {:controller=>"admin/users", :action=>"create"}
           new_admin_user GET    /admin/users/new(.:format)        {:controller=>"admin/users", :action=>"new"}
          edit_admin_user GET    /admin/users/:id/edit(.:format)   {:controller=>"admin/users", :action=>"edit"}
               admin_user GET    /admin/users/:id(.:format)        {:controller=>"admin/users", :action=>"show"}
                          PUT    /admin/users/:id(.:format)        {:controller=>"admin/users", :action=>"update"}
                          DELETE /admin/users/:id(.:format)        {:controller=>"admin/users", :action=>"destroy"}
              admin_pages GET    /admin/pages(.:format)            {:controller=>"admin/pages", :action=>"index"}
                          POST   /admin/pages(.:format)            {:controller=>"admin/pages", :action=>"create"}
           new_admin_page GET    /admin/pages/new(.:format)        {:controller=>"admin/pages", :action=>"new"}
          edit_admin_page GET    /admin/pages/:id/edit(.:format)   {:controller=>"admin/pages", :action=>"edit"}
               admin_page GET    /admin/pages/:id(.:format)        {:controller=>"admin/pages", :action=>"show"}
                          PUT    /admin/pages/:id(.:format)        {:controller=>"admin/pages", :action=>"update"}
                          DELETE /admin/pages/:id(.:format)        {:controller=>"admin/pages", :action=>"destroy"}
    

    所以你可以推导出来

    admin_user_path
    

    这将与

    相同
    user_path
    

    然后你会像这样在 admin_user_path 中传递@user:

    admin_user_path(@user)
    

    :method 应该调用 destroy 方法而不是自动转到 show 方法! :)

    为了让 form_for 工作,我找到了以下资源:http://api.rubyonrails.org/classes/ActionView/Helpers/FormHelper.html#method-i-form_for

    在 form_for 部分下,他们将使用 form_for 的命名空间路由解释为:

        For namespaced routes, like admin_post_url:
    
        <%= form_for([:admin, @post]) do |f| %>
         ...
        <% end %>
    

    有关 rake 路线 的信息,请查看:http://guides.rubyonrails.org/command_line.html#rake-is-ruby-make 然后在 2.4.9 杂项任务部分下,他们解释了 rake --tasks 向您展示了您可以使用的各种 rake 命令use 和 rake routes 显示可用的路由路径。

    希望这会有所帮助!

    【讨论】:

      猜你喜欢
      • 2012-10-15
      • 1970-01-01
      • 1970-01-01
      • 2023-04-04
      • 2018-05-05
      • 1970-01-01
      • 1970-01-01
      • 2011-10-06
      • 2010-12-21
      相关资源
      最近更新 更多