Rails:URL路径修改与命名空间的好处?

Dou*_*las 5 namespaces url-routing ruby-on-rails-3.2

许多人谈论命名空间作为一种方式来改变导致他们的控制器带有前缀的URL(即:/ admin/movies而不是/ movies)

更改URL路径

官方文档解释说,如果我们想改变这种状况导致我们的前缀控制器的URL,我们只需要改变我们的资源在配置/ route.rb.

由此 :

  resources :movies
Run Code Online (Sandbox Code Playgroud)

对此:

  resources :movies, :path => "/admin/movies"
Run Code Online (Sandbox Code Playgroud)

实现命名空间

经过大量的googsearches,我想知道为什么这么多人喜欢命名空间和命名空间的优点而不仅仅是修改导致路由器文件中特定控制器的URL路径:myapp/config/route.rb

为了实现命名空间,官方文档解释说您需要进行以下修改.你会发现这是很多工作:

  namespace :admin do
    resources :movies
  end
Run Code Online (Sandbox Code Playgroud)

...并将movies_controller.rb控制器移动到app/controllers/admin目录.

但是,如果您按照这些说明操作,则会收到以下错误:

*"预期/var/www/myapp/app/controllers/admin/movies_controller.rb定义Admin :: MoviesController"*

*然后你意识到Rails期望在你的movies_controller.rb的开头写这个"外星人"的写作:"Admin ::"*

所以你改变了movies_controller.rb的第一行:

  class admin::MoviesController < ApplicationController
Run Code Online (Sandbox Code Playgroud)

代替 :

  class MoviesController < ApplicationController
Run Code Online (Sandbox Code Playgroud)

但是你再次得到另一个错误: "未定义的局部变量或方法`admin'for main:Object"

然后你意识到你忘了Ruby类必须用起始大写声明.

所以你在Ruby类中添加一个起始大写:

  class Admin::MoviesController < ApplicationController
Run Code Online (Sandbox Code Playgroud)

但是你仍然会收到一个错误:

*缺少模板admin/movies/index,application/index with {:locale => [:"fr-CH"],:formats => [:html],:handlers => [:erb,:builder,:rxls, :咖啡,:haml]}.搜索:*"/ var/www/myapp/app/views"*

我勒个去...?哦,文档忘了说控制器的相应视图也必须移动到app/view /中的管理目录吗?

所以你创建一个目录并将你的视图移动到app/view/admin /你仍然会得到同样的错误.

然后你意识到你忘记在app/view/admin中包含电影文件夹了所以你做到了.

你仍然收到一条错误信息:*###:0xa817c0c的未定义方法`movies_path'*

这次你知道路由,控制器和视图工作,但你仍然需要更改所有视图的路径...

此外,如果在控制器文件中使用" respond_with "方法,则必须将命名空间作为参数包含在内.这是索引操作的示例:

  def index
    @movies = Movie.all
    respond_with(:admin, @movies)
  end
Run Code Online (Sandbox Code Playgroud)

此外,如果您使用declarative_authentification gem(类似于cancan gem),您必须为permited_to的参数添加前缀?命名空间的方法.例如(使用HAML语法):

- if permitted_to? :index, :admin_movies
  // And prefix as well your path
  = link_to 'Show all my movie", admin_movies_path

- if permitted_to? :show, :admin_movies
  // And prefix as well your path
  = link_to 'Show selected movie", admin_movie_path(@movie)
Run Code Online (Sandbox Code Playgroud)

您意识到您将仅为url路径协调创建命名空间,因此您决定放弃,回滚您的modif,并在route.rb文件中添加以下行:

  resources :movies, :path => "/admin/movies"
Run Code Online (Sandbox Code Playgroud)

这就像魅力一样立即起作用.

作为测试目的,我创建了一个新的假项目"testapp",包括带有生成器的命名空间.我执行了"rails generate scaffold admin/movie title:string"来检查生成器如何处理命名空间.生成的app/controller/admin/movies_controller.rb与我们的预期完全不同.每个实例变量声明前面都有附加前缀"Admin ::".这里例如索引方法:

  def index
    @admin_movies = Admin::Movie.all

    respond_to do |format|
      format.html # index.html.erb
      format.json { render json: @admin_movies }
    end
  end
Run Code Online (Sandbox Code Playgroud)

我想这是因为生成器将模型movie.rb移动到app/models/admin目录中

此外,我看到app/models中还有另一个模型:admin.rb其中包含:

  module Admin
    def self.table_name_prefix
      'admin_'
    end
  end
Run Code Online (Sandbox Code Playgroud)

我不知道这个方法将如何使用,也不知道是谁?

我还注意到我的表将在/db/migrate/2012blabla_create_admin_movies.rb中命名为"admin_movies"

  class CreateAdminMovies < ActiveRecord::Migration
    def change
      create_table :admin_movies do |t|

        t.timestamps
      end
    end
  end
Run Code Online (Sandbox Code Playgroud)

好吧,为了实现命名空间,似乎会有比我预期更多的工作(和搞乱)......

为了什么好处/优势???

  1. 要使用其他网址路径?我的控制器中的这个小修改会容易得多:资源:电影,:path =>"/ admin/movies"
  2. 为了能够使用两个使用相同名称的不同控制器?将这个前缀添加到我的控制器名称不是比这一切搞乱更容易吗?

当然,通过更加警惕可以避免上述一些错误.但是你知道,我们只是人类,而当编码的时候已经很晚了,也许你希望这部分轨道可以说,更适合人类......

我真的不明白为什么人们对命名空间感到兴奋.如果专家可以解释我错过了什么,我将不胜感激.

非常感谢

pra*_*ase 1

如果您有两个名称相同但功能不同的不同控制器,则可以使用命名空间路由。您不必为其重命名控制器。查看“2.6 控制器命名空间和路由”:http://guides.rubyonrails.org/routing.html