`
andyhu1007
  • 浏览: 199471 次
  • 性别: Icon_minigender_1
  • 来自: 北京
文章分类
社区版块
存档分类
最新评论

Rails每周一题(二): routes

阅读更多

Rails其实很好懂,可视的源码和大量的注释,只看你有没有心去一窥究竟。今天就来看看貌似神秘的routes吧。

一个命令

首先,介绍一个rake命令。对于不了解routes定义规则的,或许看到routes.rb文件有点迷糊。不要紧,如果你想看看一个url到底对应了哪个controller以及action,就用rake routes展开所有的奥秘吧。

几多规则

routes的定义规则其实不多,让我们来一一分析下吧。不过要保持耐心。

分析routes.rb文件,首先得搞清楚,它的优先级是从上到下,谁先匹配谁先得。

1. 默认规则

 

  # Install the default routes as the lowest priority.
  # Note: These default routes make all actions in every controller accessible via GET requests. You should
  # consider removing the them or commenting them out if you're using named routes and resources.
  map.connect ':controller/:action/:id'
  map.connect ':controller/:action/:id.:format'

 

  自定义的路由规则往往需要覆盖默认的路由规则,所以,rails的routes模板把默认路由规则放在文件的最下面,并且鼓励考虑用具名路由替换它们。

2. 无名规则

  大家看到前面的map.connect,那么这个方法到底做了什么?

  # Create an unnamed route with the provided +path+ and +options+. See
  # ActionController::Routing for an introduction to routes.
  def connect(path, options = {})
     @set.add_route(path, options)
  end

 

  可以看到,connect方法为我们生成了一个无名路由规则。

  我们可以如此生成一个无名规则:

map.connect 'products/:id', :controller => 'catalog', :action => 'view'


3. 具名规则
 
  为什么要有具名规则,主要是因为rails可以为具名规则生成一些url helper。关于routes的helper,待会儿再详细描述,先来看看具名规则吧。

 

map.purchase 'products/:id/purchase', :controller => 'catalog', :action => 'purchase'


  如此,我们已经生成了一个名字叫做purchase的具名规则。
 
  看看源代码

def named_route(name, path, options = {}) #:nodoc:
    @set.add_named_route(name, path, options)
end


4. 单资源REST风格路由规则: map.resource

   我们定义这样一个规则: map.resource :account

 

   它会帮我们定义怎样的一个路由规则呢? 答案是一个遵循REST风格的路由规则,非常完美。

 

  # maps these actions in the Accounts controller:
  class AccountsController < ActionController::Base
      # GET new_account_url
       def new
         # return an HTML form for describing the new account
      end
    
      # POST account_url
      def create
        # create an account
      end
   
      # GET account_url
      def show
        # find and return the account
      end
    
     # GET edit_account_url
      def edit
        # return an HTML form for editing the account
      end
   
      # PUT account_url
      def update
        # find and update the account
      end
    
     # DELETE account_url
      def destroy
        # delete the account
      end
   end
 

    让我们用rake routes看看它为我们生成了怎样的路由。

 

    account POST                                     /account                            {:controller=>"accounts", :action=>"create"}
    formatted_account POST                 /account.:format               {:controller=>"accounts", :action=>"create"}
    new_account GET                             /account/new                    {:controller=>"accounts", :action=>"new"}
    formatted_new_account GET         /account/new.:format       {:controller=>"accounts", :action=>"new"}
    edit_account GET                             /account/edit                     {:controller=>"accounts", :action=>"edit"}
    formatted_edit_account GET          /account/edit.:format        {:controller=>"accounts", :action=>"edit"}
    GET                                                     /account                              {:controller=>"accounts", :action=>"show"}
    GET                                                     /account.:format                 {:controller=>"accounts", :action=>"show"}
    PUT                                                     /account                               {:controller=>"accounts", :action=>"update"}
    PUT                                                      /account.:format                 {:controller=>"accounts", :action=>"update"}
    DELETE                                             /account                               {:controller=>"accounts", :action=>"destroy"}
    DELETE                                             /account.:format                 {:controller=>"accounts", :action=>"destroy"}
      

5. 集合资源REST风格路由规则

 

    我们定义一个这样的规则: map.resources :messages

 

   #   map.resources :messages
 
    # will map the following actions in the corresponding controller:
      class MessagesController < ActionController::Base
       # GET messages_url
       def index
         # return all messages
       end
    
      # GET new_message_url
       def new
         # return an HTML form for describing a new message
       end
    
       # POST messages_url
       def create
         # create a new message
       end
   
     # GET message_url(:id => 1)
       def show
         # find and return a specific message
       end
   
     # GET edit_message_url(:id => 1)
       def edit
         # return an HTML form for editing a specific message
       end
   
       # PUT message_url(:id => 1)
       def update
         # find and update a specific message
       end
    
       # DELETE message_url(:id => 1)
       def destroy
         # delete a specific message
       end
     end

 

     messages GET                          /messages                                {:controller=>"messages", :action=>"index"}
     formatted_messages GET       /messages.:format                   {:controller=>"messages", :action=>"index"}
     POST                                           /messages                                {:controller=>"messages", :action=>"create"}
     POST                                           /messages.:format                   {:controller=>"messages", :action=>"create"}
     new_user GET                           /messages/new                       {:controller=>"messages", :action=>"new"}
     formatted_new_user GET       /messages/new.:format          {:controller=>"messages", :action=>"new"}
     edit_user GET                             /messages/:id/edit                  {:controller=>"messages", :action=>"edit"}
     formatted_edit_user GET        /messages/:id/edit.:format      {:controller=>"messages", :action=>"edit"}
     user GET                                      /messages/:id                          {:controller=>"messages", :action=>"show"}
     formatted_user GET                   /messages/:id.:format             {:controller=>"messages", :action=>"show"}
      PUT                                              /messages/:id                           {:controller=>"messages", :action=>"update"}
      PUT                                             /messages/:id.:format              {:controller=>"messages", :action=>"update"}
     DELETE                                        /messages/:id                          {:controller=>"messages", :action=>"destroy"}
      DELETE                                     /messages/:id.:format            {:controller=>"messages", :action=>"destroy"}



6. 嵌套规则

 

    简单嵌套规则

 

map.resources :products, :has_many => [ :comments, :sales ], :has_one => :seller
 

    用rake routes看看生成的路由规则,即可一目了然。


     一个更加复杂的嵌套规则

 

map.resources :products do |products|
    products.resources :comments
    products.resources :sales, :collection => { :recent => :get }
end
 

7. root

# You can have the root of your site routed with map.root -- just remember to delete public/index.html.
map.root :controller => 'home'  
 

     root路由用于映射根目录。

8. namespace

 

     我们还可以定义一个命名空间,如这样。

 

 

map.namespace :admin do |admin|
    # Directs /admin/products/* to Admin::ProductsController (app/controllers/admin/products_controller.rb)
   admin.resources :products
end

 

7. path_prefix, name_prefix等其他options

 

    当想让不同的method访问同一个url时,对应到不同的controller或者action,可以如是:

 

 

map.signup '/signup', :controller => 'people', :action => 'new', :conditions => {:method => :get}
map.signup '/signup', :controller => 'people', :action => 'create', :conditions => {:method => :post}
 

    还是不再赘述了,这样的option很多,在不明白的时候,不如直接看源代码吧。
 

routes helpers

 

    当我们定义了一个具名路由或者REST风格路由时,router helper会为我们生成一些帮助方法。

 

    比如当我们定义了一个这样的路由时:

 

map.purchase 'products/:id/purchase', :controller => 'catalog', :action => 'purchase'

 

     生成的helper方法有:

 

     purchase_url(:id => 1)  #  http://test.url/products/1/purchase

     purchase_path(:id => 1)  #  /products/1/purchase

     hash_for_purchase_url(:id => 1)   # {:controller=>"sessions", :action=>"new", :use_route=>:new_session, :only_path=>false}

     hash_for_purchase_path(:id => 1)  # {:controller=>"sessions", :action=>"new", :use_route=>:new_session, :only_path=>true}

 

delete & put

 

     对delete和put method,现在大多数浏览器都不能处理,所以以post方法代替,并附上:method参数。

 

 

<% form_for :message, @message, :url => message_path(@message), :html => {:method => :put} do |f| %>  
 

保持简单

 

     最后有点感触,随着项目的进行,routes会变得越来越复杂,越来越难以看懂。所以,我们要遵循保持简单,尽量使用REST风格的原则。

分享到:
评论
1 楼 222xiaohuan 2009-04-01  
<div class="quote_title">andyhu1007 写道</div>
<div class="quote_div">
<p>Rails其实很好懂,可视的源码和大量的注释,只看你有没有心去一窥究竟。今天就来看看貌似神秘的routes吧。<br />
<br />
<strong>一个命令</strong>
<br />
<br />
首先,介绍一个rake命令。对于不了解routes定义规则的,或许看到routes.rb文件有点迷糊。不要紧,如果你想看看一个url到底对应了哪个controller以及action,就用rake routes展开所有的奥秘吧。<br />
<br />
<strong>几多规则<br />
<br />
</strong>
routes的定义规则其实不多,让我们来一一分析下吧。不过要保持耐心。<br />
<br />
分析routes.rb文件,首先得搞清楚,它的优先级是从上到下,谁先匹配谁先得。<br />
<br />
1. 默认规则</p>
<p> </p>
<pre name="code" class="ruby">  # Install the default routes as the lowest priority.
  # Note: These default routes make all actions in every controller accessible via GET requests. You should
  # consider removing the them or commenting them out if you're using named routes and resources.
  map.connect ':controller/:action/:id'
  map.connect ':controller/:action/:id.:format'</pre>
<p> </p>
<p>
  自定义的路由规则往往需要覆盖默认的路由规则,所以,rails的routes模板把默认路由规则放在文件的最下面,并且鼓励考虑用具名路由替换它们。<br />
<br />
2. 无名规则<br />
<br />
  大家看到前面的map.connect,那么这个方法到底做了什么?</p>
<pre name="code" class="ruby">  # Create an unnamed route with the provided +path+ and +options+. See
  # ActionController::Routing for an introduction to routes.
  def connect(path, options = {})
     @set.add_route(path, options)
  end</pre>
<p> </p>
<p>
  可以看到,connect方法为我们生成了一个无名路由规则。<br />
<br />
  我们可以如此生成一个无名规则:</p>
<pre name="code" class="ruby">map.connect 'products/:id', :controller =&gt; 'catalog', :action =&gt; 'view'</pre>
<p>
<br />
3. 具名规则<br />
 <br />
  为什么要有具名规则,主要是因为rails可以为具名规则生成一些url helper。关于routes的helper,待会儿再详细描述,先来看看具名规则吧。</p>
<p> </p>
<pre name="code" class="ruby">map.purchase 'products/:id/purchase', :controller =&gt; 'catalog', :action =&gt; 'purchase'</pre>
<p>
<br />
  如此,我们已经生成了一个名字叫做purchase的具名规则。<br />
 <br />
  看看源代码</p>
<pre name="code" class="ruby">def named_route(name, path, options = {}) #:nodoc:
    @set.add_named_route(name, path, options)
end</pre>
<p>
<br />
4. 单资源REST风格路由规则: map.resource<br />
<br />
   我们定义这样一个规则: map.resource :account</p>
<p> </p>
<p>   它会帮我们定义怎样的一个路由规则呢? 答案是一个遵循REST风格的路由规则,非常完美。</p>
<p> </p>
<pre name="code" class="ruby">  # maps these actions in the Accounts controller:
  class AccountsController &lt; ActionController::Base
      # GET new_account_url
       def new
         # return an HTML form for describing the new account
      end
   
      # POST account_url
      def create
        # create an account
      end
  
      # GET account_url
      def show
        # find and return the account
      end
   
     # GET edit_account_url
      def edit
        # return an HTML form for editing the account
      end
  
      # PUT account_url
      def update
        # find and update the account
      end
   
     # DELETE account_url
      def destroy
        # delete the account
      end
   end</pre>
 
<p>    让我们用rake routes看看它为我们生成了怎样的路由。</p>
<p> </p>
<p>    account POST                                     /account                            {:controller=&gt;"accounts", :action=&gt;"create"}<br />
    formatted_account POST                 /account.:format               {:controller=&gt;"accounts", :action=&gt;"create"}<br />
    new_account GET                             /account/new                    {:controller=&gt;"accounts", :action=&gt;"new"}<br />
    formatted_new_account GET         /account/new.:format       {:controller=&gt;"accounts", :action=&gt;"new"}<br />
    edit_account GET                             /account/edit                     {:controller=&gt;"accounts", :action=&gt;"edit"}<br />
    formatted_edit_account GET          /account/edit.:format        {:controller=&gt;"accounts", :action=&gt;"edit"}<br />
    GET                                                     /account                              {:controller=&gt;"accounts", :action=&gt;"show"}<br />
    GET                                                     /account.:format                 {:controller=&gt;"accounts", :action=&gt;"show"}<br />
    PUT                                                     /account                               {:controller=&gt;"accounts", :action=&gt;"update"}<br />
    PUT                                                      /account.:format                 {:controller=&gt;"accounts", :action=&gt;"update"}<br />
    DELETE                                             /account                               {:controller=&gt;"accounts", :action=&gt;"destroy"}<br />
    DELETE                                             /account.:format                 {:controller=&gt;"accounts", :action=&gt;"destroy"}<br />
       <br />
<br />
5. 集合资源REST风格路由规则</p>
<p> </p>
<p>    我们定义一个这样的规则: map.resources :messages</p>
<p> </p>
<pre name="code" class="ruby">   #   map.resources :messages

    # will map the following actions in the corresponding controller:
      class MessagesController &lt; ActionController::Base
       # GET messages_url
       def index
         # return all messages
       end
   
      # GET new_message_url
       def new
         # return an HTML form for describing a new message
       end
   
       # POST messages_url
       def create
         # create a new message
       end
  
     # GET message_url(:id =&gt; 1)
       def show
         # find and return a specific message
       end
  
     # GET edit_message_url(:id =&gt; 1)
       def edit
         # return an HTML form for editing a specific message
       end
  
       # PUT message_url(:id =&gt; 1)
       def update
         # find and update a specific message
       end
   
       # DELETE message_url(:id =&gt; 1)
       def destroy
         # delete a specific message
       end
     end</pre>
<p> </p>
<p>     messages GET                          /messages                                {:controller=&gt;"messages", :action=&gt;"index"}<br />
     formatted_messages GET       /messages.:format                   {:controller=&gt;"messages", :action=&gt;"index"}<br />
     POST                                           /messages                                {:controller=&gt;"messages", :action=&gt;"create"}<br />
     POST                                           /messages.:format                   {:controller=&gt;"messages", :action=&gt;"create"}<br />
     new_user GET                           /messages/new                       {:controller=&gt;"messages", :action=&gt;"new"}<br />
     formatted_new_user GET       /messages/new.:format          {:controller=&gt;"messages", :action=&gt;"new"}<br />
     edit_user GET                             /messages/:id/edit                  {:controller=&gt;"messages", :action=&gt;"edit"}<br />
     formatted_edit_user GET        /messages/:id/edit.:format      {:controller=&gt;"messages", :action=&gt;"edit"}<br />
     user GET                                      /messages/:id                          {:controller=&gt;"messages", :action=&gt;"show"}<br />
     formatted_user GET                   /messages/:id.:format             {:controller=&gt;"messages", :action=&gt;"show"}<br />
      PUT                                              /messages/:id                           {:controller=&gt;"messages", :action=&gt;"update"}<br />
      PUT                                             /messages/:id.:format              {:controller=&gt;"messages", :action=&gt;"update"}<br />
     DELETE                                        /messages/:id                          {:controller=&gt;"messages", :action=&gt;"destroy"}<br />
      DELETE                                     /messages/:id.:format            {:controller=&gt;"messages", :action=&gt;"destroy"}</p>
<p>
<br />
<br />
6. 嵌套规则</p>
<p> </p>
<p>    简单嵌套规则</p>
<p> </p>
<pre name="code" class="ruby">map.resources :products, :has_many =&gt; [ :comments, :sales ], :has_one =&gt; :seller</pre>
 
<p>    用rake routes看看生成的路由规则,即可一目了然。</p>
<p><br />
     一个更加复杂的嵌套规则</p>
<p> </p>
<pre name="code" class="ruby">map.resources :products do |products|
    products.resources :comments
    products.resources :sales, :collection =&gt; { :recent =&gt; :get }
end</pre>
 
<p>
7. root</p>
<pre name="code" class="ruby"># You can have the root of your site routed with map.root -- just remember to delete public/index.html.
map.root :controller =&gt; 'home'  </pre>
 
<p>     root路由用于映射根目录。<br />
<br />
8. namespace</p>
<p> </p>
<p>     我们还可以定义一个命名空间,如这样。</p>
<p> </p>
<p> </p>
<pre name="code" class="ruby">map.namespace :admin do |admin|
    # Directs /admin/products/* to Admin::ProductsController (app/controllers/admin/products_controller.rb)
   admin.resources :products
end</pre>
<p> </p>
<p>
7. path_prefix, name_prefix等其他options</p>
<p> </p>
<p>    还是不再赘述了,这样的option很多,在不明白的时候,不如直接看源代码吧。<br />
  <br />
<br />
<strong>routes helpers<br />
</strong>
</p>
<p> </p>
<p>    当我们定义了一个具名路由或者REST风格路由时,router helper会为我们生成一些帮助方法。</p>
<p> </p>
<p>    比如当我们定义了一个这样的路由时:</p>
<p> </p>
<pre name="code" class="ruby">map.purchase 'products/:id/purchase', :controller =&gt; 'catalog', :action =&gt; 'purchase'</pre>
<p> </p>
<p>     生成的helper方法有:</p>
<p> </p>
<p>     purchase_url(:id =&gt; 1)  #  http://test.url/products/1/purchase</p>
<p>     purchase_path(:id =&gt; 1)  #  /products/1/purchase</p>
<p>     hash_for_purchase_url(:id =&gt; 1)   # {:controller=&gt;"sessions", :action=&gt;"new", :use_route=&gt;:new_session,nly_path=&gt;false}</p>
<p>     hash_for_purchase_path(:id =&gt; 1)  # {:controller=&gt;"sessions", :action=&gt;"new", :use_route=&gt;:new_session,nly_path=&gt;true}</p>
<p> </p>
<p><strong>
delete &amp; put<br />
</strong>
</p>
<p> </p>
<p>     对delete和put method,现在大多数浏览器都不能处理,所以以post方法代替,并附上:method参数。</p>
<p> </p>
<p> </p>
<pre name="code" class="ruby">&lt;% form_for :message, @message, :url =&gt; message_path(@message), :html =&gt; {:method =&gt; :put} do |f| %&gt;  </pre>
 
<p>
<strong>保持简单</strong>
</p>
<p> </p>
<p>     最后有点感触,随着项目的进行,routes会变得越来越复杂,越来越难以看懂。所以,我们要遵循保持简单,尽量使用REST风格的原则。</p>
</div>
<p> </p>

相关推荐

    Rails的精简版本Rails::API.zip

    Rails::API 是 Rails 的精简版本,针对不需要使用完整 Rails 功能的开发者。 Rails::API 移除了 ActionView 和其他一些渲染功能,不关心Web前端的开发者可更容易、快速地开发应用程序,因此运行速度比正常的 Rails ...

    Rails上的API:使用Rails构建REST APIAPIs on Rails: Building REST APIs with Rails

    在本篇内容中,我们将深入探讨如何利用Ruby on Rails(简称Rails)这一强大的Web应用程序框架来构建可伸缩且易于维护的RESTful API。Rails以其简洁优雅的语法、高效的开发速度以及良好的社区支持而闻名,这使得它...

    Ruby on Rails入门例子

    Ruby on Rails,简称Rails,是一种基于Ruby语言的开源Web应用程序框架,它遵循MVC(Model-View-Controller)架构模式,旨在使Web开发过程更加高效、简洁。本篇将通过一个入门实例,深入探讨Rails的基本概念和核心...

    Ruby on Rails入门经典代码

    Ruby on Rails,简称Rails,是基于Ruby语言的一个开源Web应用程序框架,它遵循MVC(Model-View-Controller)架构模式,旨在使Web开发过程更加高效、简洁。本压缩包中的"Ruby on Rails入门经典代码"提供了新手学习...

    rails-ansible-presentation:有关Rails + Ansible的Deckset演示

    [适合] Rails :red_heart: Ansible [适合] Rails :red_heart: Ansible (有一点帮助) Rails部署 简单吧? 将应用程序放在服务器上。 捆绑宝石。 应用迁移。 重新启动服务。 Easy Rails部署 git push master ...

    rails-basic-template:基本 Rails 模板

    Rails 基本模板参考: : Ruby on Rails Gemfile:定义应用程序正在使用的库的文件bundle install:基于Gemfile,安装所有库每次修改 Gemfile 时都应该运行bundle install gem 是 Ruby 的库RubyGems.org 是一个查找和...

    rails-routes:在Rails应用程序上启用configroutes * .rb

    gem "rails-routes" 然后执行: $ bundle 或自己安装为: $ gem install rails-routes 用法 将这个gem添加到您的项目后,您可以在config/routes创建多个路由文件。 只要确保您用 # config/routes/v1.rb Rails . ...

    rails_console_toolkit:可配置的 Rails 控制台助手

    RailsConsole 工具包 :wrench: :toolbox: 可配置的 Rails 控制台助手更快地查找记录,添加自定义助手,将您的控制台寿命提高 100%。安装将此行添加到应用程序的 Gemfile 中: gem 'rails_console_toolkit' 然后生成...

    rails_email_preview:在Rails中预览和编辑应用程序邮件模板

    安装加 到Gemfile: gem 'rails_email_preview' , '~&gt; 2.2.2' 添加一个初始化程序和路由: $ rails g rails_email_preview:install 在app / mailer_previews /中生成预览类和方法存根$ rails g rails_email_preview:...

    Rails相关电子书汇总二

    标题 "Rails相关电子书汇总二" 提供的信息表明,这个压缩包包含的是一些关于Rails框架的高级主题的电子书籍资源。Rails是一个流行的开源Web应用框架,基于Ruby编程语言,它遵循模型-视图-控制器(MVC)架构模式,为...

    webpack-rails, 将 web pack与你的Ruby on Rails 应用程序集成.zip

    webpack-rails, 将 web pack与你的Ruby on Rails 应用程序集成 不再维护webpack-rails 不再被维护。 有关详细信息,请参阅 #90. web pack-railsweb pack 为你提供了将 web pack集成到现有的Ruby on Rails 应用程序中...

    rails-developer-scanning:针对Rails开发人员的自动面试问题

    标题 "rails-developer-scanning" 指向的是一个针对Rails开发者设计的自动化面试工具,旨在帮助面试官或招聘者快速有效地评估应聘者的Rails技能。这个工具名为 "jyaasa_interviewer",通过RubyGem安装,使得面试过程...

    rails-dom-testing:从ActionView中提取DomAssertions和SelectorAssertions

    Rails :: Dom :: Testing 这个gem负责比较HTML DOM并断言Rails应用程序中存在DOM元素。 assert_dom_equal通过assert_dom_equal和assert_dom_not_equal进行比较。 元素通过assert_dom , assert_dom_encoded , ...

    Ruby On Rails 面试系列七,一个面试练习题

    这个面试练习题可能是为了测试应聘者对于Rails应用的构建、自动化任务管理、测试驱动开发(TDD)以及文件组织结构的理解。让我们逐一探讨这些知识点。 首先,`Rakefile`是Ruby中的构建工具,类似于其他语言的...

    Rails相关电子书汇总

    4. **路由(Routes)**:Rails的路由系统将URL请求映射到特定的控制器动作,实现了URL和应用逻辑之间的解耦。 5. **辅助方法(Helper Methods)**:为视图提供便利的功能,如链接生成、样式辅助等。 6. **Scaffold...

    js-routes:将名为Rails的路由引入javascript

    路由 生成将所有以Rails命名的路由定义为javascript助手的javascript文件安装您的Rails Gemfile: gem "js-routes"设置跑: rake js:routes在app/javascript/packs/application.js中使路由全局可用: window ....

    rails-controller-testing:将`assigns`和`assert_template`带回到您的Rails测试中

    Rails :: Controller :: Testing 这个gem将assigns给控制器测试的内容以及assert_template带回assigns控制器和集成测试的内容。 这些方法已中。 安装 将此行添加到您的应用程序的Gemfile中: gem 'rails-...

    rails_stack-cookbook:使用 nginx、unicorn、redis 等设置 Rails 环境的 Chef 食谱

    rails_stack 食谱 TODO:在此处输入食谱说明。 例如,这本食谱使您最喜欢的早餐三明治。 要求 TODO:列出您的食谱要求。 确保包含本说明书对平台、库、其他说明书、软件包、操作系统等的任何要求。 例如 包裹 ...

    rails-cache-extended:帮助程序和日志记录添加到 Rails 缓存

    Rails::Cache::Extended 这允许为记录集合生成自动过期的缓存键 安装 将此行添加到应用程序的 Gemfile 中: gem 'rails-cache-extended' 然后执行: $ bundle 或者自己安装: $ gem install rails-cache-...

Global site tag (gtag.js) - Google Analytics