Rails 总结了下 routes 的使用

heroyct · 2018年08月30日 · 最后由 heroyct 回复于 2018年09月10日 · 949 次阅读

总结了一下目前开发中写routes的时候遇到的各种情况以及如何解决的

routes简介

什么是routes

简单来说就是把HTTP Request匹配到对应的action(定义在controller里)

如何定义

在config/routes.rb里面定义,类似于这样

Rails.application.routes.draw do 
  resource :books, only: [:index, :show]
end

如何查看已经定义好的routes

$ bundle exec rake routes

根据subdomain来分配路由

比如网站管理画面希望用 http://admin.your-site/ 来访问

constraints subdomain: 'admin' do
  scope module: 'admin' do
    resources :books
  end
end

这样只有subdomain是admin的时候才会匹配admin下面对应的路由

根据domain来分配路由

1. 定义domain的匹配

#lib/constraints/domain_constraint.rb

class Constraints::DomainConstraint

  def initialize(domain)
    @domain = [domain].flatten
  end

  def matches?(request)
    @domain.include? request.domain
  end
end

2. 在config/routes.rb里面定义对应的routes

# config/routes.rb:

constraints DomainConstraint.new('app1') do
  resources :app1
end

constraints DomainConstraint.new('app2') do
  resources :app2
end

redirect

get '/test', to: redirect('/to_url')
  • 注意routes里面定义的redirect的http status是301,而controller里面的direct是302
  • 因为对SEO有一定影响,如果是永久性的转移建议定义在routes或者nginx之类的web服务器上面

用routes定义好的名字

= link_to 'book', books_path
= link_to 'book', controller: "books", action: "index"

用bechmark来测试的话,或发现第一种写法要快上一倍
尽量使用定义好的url_path,也可以用as来自己定义名字

get '/books' => 'books#index', as: 'books'

对url的参数进行限制

比如id只想要整数,可以这样进行限制

get 'books/:id', constraints: { id: /[1-9][0-9]*/ }

只匹配限定的参数

get 'books/:type', constraints: { type: Regexp.union(['type1','type2','type3']) }

限制用户的权限

使用devise的话,可以像下面这样限制admin权限的用户才可以访问sidekiq管理画面

authenticate :operator, lambda { |o| o.admin? } do
  mount Sidekiq::Web => '/sidekiq'
end

将routes分割为多个文件

当routes.rb太大的时候,我们可能会想要分离为多个文件来方便管理

1. config/routes里面进行如下定义

# config/routes.rb:

Rails.application.routes.draw do
  def draw(routes_name)
    instance_eval(File.read(Rails.root.join("config/routes/#{routes_name}.rb")))
  end

  draw :user

  constraints subdomain: 'admin' do
    draw :admin
  end

  match '*path', to: 'application#render_404', via: :all
end

2. 在config/routes/ 文件夹下面添加routes定义文件

文件结构

config/routes/
├── admin.rb
└── user.rb

对应的文件

# config/routes/user.rb
resources :books
# config/routes/admin.rb

resources :authors
共收到 3 条回复

不错,插眼

这样分文件的话 要注意配置一下eager load path

@matrixbirds

这样分文件的话 要注意配置一下eager load path

能详细说一下吗?目前用的是rails 4.2,没有进行其他配置

是这类问题吗? https://blog.arkency.com/2014/11/dont-forget-about-eager-load-when-extending-autoload/ https://stackoverflow.com/questions/48538755/eager-load-all-classes-before-routes-rb-being-loaded

需要 登录 后方可回复, 如果你还没有账号请点击这里 注册