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

Rails每周闲碎(三): Controller

阅读更多

1. Filter

 

    Filters enable controllers to run shared pre- and post-processing code for its actions. These filters can be used to do authentication, caching, or auditing before the intended action is performed. Or to do localization or output compression after the action has been performed. Filters have access to the request, response, and all the instance variables set by other filters in the chain or by the action (in the case of after filters).

 

    Filter的功能很强大,包括before filter,after filter和aroud filter;filter的类型可以是一个方法,一个proc,也可以是一个类或者对象;filter还可以定制顺序,成为filter chain。

 

   具体详情还是请见:http://api.rubyonrails.org/classes/ActionController/Filters/ClassMethods.html

 

    Filter的顺序

 

    有时候我们会关心filter之间的顺序。比如我们定义了一个transaction filter(around filter),这个filter的作用是在非get的请求上包一个transaction,以保证数据的一致性。

 

    如果我们还定义了一个after filter,它会插入一些新数据或者对数据做一些变更。我们同样希望它能在transaction内,这时候filter之间的顺序就很重要。

 

    对同一类filter,Rails可以定制它们的顺序(请见http://api.rubyonrails.org/classes/ActionController/Filters/ClassMethods.html )。但对不同类filter之间的顺序,rails并没有提供api来定制它们的顺序。就比如上面所提到的一个around filter和一个after filter之间的顺序。

 

    根据观察,它们之间的顺序应该跟声明顺序有关:声明越在前的filter越在filter chain的内部。以上面那个为例,如果transaction filter先于OneAfterFilter定义:

 

 

    OneBeforeFilter#before  
      TransactionFilter#before
        # run the action
      TransactionFilter#after
    OneAfterFilter#after

 

    Transaction并没有把OneAfterFilter包括在内。但这没有保证。所以在使用需要明确顺序的filter时要注意。

 

2. Ajax redirect?

 

   不要奢望用normal http response的那种方式来redirect(通过response header),ajax的机制是不一样的,看看下面这段:

 

   XMLHttpRequest (XHR ) is a DOM API that can be used inside a web browser scripting language , such as JavaScript , to send an HTTP or an HTTPS request directly to a web server and load the server response data directly back into the scripting language [ 1] . Once the data is within the scripting language, it is available as both an XML document, if the response was valid XML markup [ 2] , and as plain text [ 3] . The XML data can be used to manipulate the currently active document in the browser window without the need of the client loading a new web page document. Plain text data can be evaluated within the scripting language to manipulate the document, too; in the example of JavaScript, the plain text may be formatted as JSON by the web server and evaluated within JavaScript to create an object of data for use on the current DOM.

 

   那如何在ajax response中实现redirect?rails的代码很简单:

 

 

render :update do |page|
  page.redirect_to some_path
end

 

  背后的实现:

 

 

def redirect_to(location)
  # some other code
  record "window.location.href = #{url.inspect}"
end

 

 

3. ActionController::Streaming

 

    Methods for sending files and streams to the browser instead of rendering.

     http://guides.rubyonrails.org/action_controller_overview.html#streaming-and-file-downloads

 

     特别注意到上面这个页面中提及的RESTful url的例子,对于下载一个client的pdf的行为,并不需要定义一个新的action:

 

 

class ClientsController < ApplicationController 
  # The user can request to receive this resource as HTML or PDF.  
  def show 
     @client = Client.find(params[:id])  
     respond_to do |format| 
       format.html 
       format.pdf { render :pdf => generate_pdf(@client) } 
     end  
  end 
end 

 

   在config/initializers/mime_types.rb :注册一种mime type:

 

 

Mime::Type.register "application/pdf", :pdf 
 

   url请求:

 

 

GET /clients/1.pdf 
 

 

4 . render :partial => 'shared/search', locals => {:objects => ... }

 

 

   Why do we need locals ? Partial is designed for reuse , so, you donot have to have the same name instance variable in your action, and locals make the reuse possible.

 

 

5. respond_to

 

 

respond_to do |format|
      format.html # do nothing, allow Rails to render index.rhtml
      format.js # do nothing, allow Rails to render index.rjs
      format.xml { render :xml => @some_thing.to_xml }
end

 

    根据HTTP头部的Accept-Type值进行相应操作。

 

6.  Security

 

    在ApplicationController里面有一句

  # See ActionController::RequestForgeryProtection for details
  # Uncomment the :secret if you're not using the cookie session store
  protect_from_forgery # :secret => 'aacb6ea3f7484b1a5b56c2d8f45121c3'

 

   这是对Cross-site request forgery 的一种防御。

 

   对于由rails的一些html helper方法生成的html里面(比如form_for等post相关的html),会自动加上一个hidden的参数authenticity_token:

 

 

<% form_for @user do |f| -%>  
  <%= f.text_field :username %>  
  <%= f.text_field :password -%> 
<% end -%> 
 
<form action="/users/1" method="post"> 
  <input type="hidden" value="67250ab105eb5ad10851c00a5621854a23af5489"  
     name="authenticity_token"/> 
  <!-- fields --> 
</form> 
 

   对于不能自动生成的地方,可以用form_authenticity_token方法生成 authenticity_token。

 

 

7. Access controller information in views.

 

    controller.controller_path => Converts the class name from something like "OneModule::TwoModule::NeatController" to "one_module/two_module/neat".

    controller.controller_name => Converts the class name from something like "OneModule::TwoModule::NeatController" to "neat".

    controller.controller_class_name  => Converts the class name from something like "OneModule::TwoModule::NeatController" to "NeatController".

 

    Of course, you can access this in the controller directly.

 

8. Parameters

 

   Rails对get和post请求的参数并不做区分。

 

   Rails对Array和Hash类的参数有很方便的支持:

 

 

GET /clients?ids[]=1&ids[]=2&ids[]=3

 

 

<form action="/clients" method="post">  
    <input type="text" name="client[name]" value="Acme" />  
    <input type="text" name="client[phone]" value="12345" />  
    <input type="text" name="client[address][postcode]" value="12345" />  
    <input type="text" name="client[address][city]" value="Carrot City" /> 
</form> 

 

 

    Prameter还有另外一种形式,routes中的parameter。这种参数出现在url中,但不跟上面query string的参数一样:

 

 

map.connect "/clients/:status"

 

    另外,我们有时候需要给每个url都加上一个默认参数:

 

 

class ApplicationController < ActionController::Base 
  # The options parameter is the hash passed in to 'url_for'  
  def default_url_options(options)  
      {:locale => I18n.locale} 
  end 
end 

 

9. Session

 

   http://guides.rubyonrails.org/action_controller_overview.html#session

 

   介绍了几种session存储方式,以及如何配置session存储方式:

 

 

# Use the database for sessions instead of the cookie-based default, # which shouldn't be used to store highly confidential information 
# (create the session table with "rake db:sessions:create") 
# ActionController::Base.session_store = :active_record_store 

 

    最重要的,介绍了CookieStore这种方式:

 

 

# Your secret key for verifying cookie session data integrity. 
# If you change this key, all old sessions will become invalid! 
# Make sure the secret is at least 30 characters and all random, 
# no regular words or you'll be exposed to dictionary attacks. 
ActionController::Base.session = {  
  :key => '_yourappname_session',  
  :secret => '4f50711b8f0f49572...' } 

 

    同时,提到session的获取是一种lazy load的方式,所以不需要因为性能问题在任何时候关闭。

 

 

10. Cookie

 

    http://guides.rubyonrails.org/action_controller_overview.html#cookies

 

    介绍了cookie的add和remove,跟session一样,它也可以像一个hash一样处理。

 

11. Verification

 

    http://guides.rubyonrails.org/action_controller_overview.html#verification

 

 

class LoginsController < ApplicationController 
  verify :params => [:username, :password],  
           :render => {:action => "new"},  
           :add_flash => {  :error => "Username and password required to log in"  },  
            :only => :create # Run only for the "create" action 
end 

 

12. Rescue

 

   匹配exception和错误页面。

 

   http://guides.rubyonrails.org/action_controller_overview.html#rescue

 

13. head

 

     returns a response that has no content (merely headers): http://api.rubyonrails.org/classes/ActionController/Base.html#M000660

 

 

3
0
分享到:
评论

相关推荐

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

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

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

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

    Ruby on Rails入门例子

    Ruby on Rails,简称Rails,是一种基于Ruby语言的开源Web应用程序框架,它遵循MVC(Model-View-Controller)架构模式,旨在使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开发过程更加高效、简洁。本压缩包中的"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中应用Ext.tree:以中国的省市地区三级联动选择为例

    在Ruby on Rails(Rails)框架中,开发人员经常需要实现各种用户交互功能,例如三级联动选择,这在处理如中国省市区这样的地理数据时尤其常见。这篇博客文章“Rails中应用Ext.tree:以中国的省市地区三级联动选择为...

    Rails3常用命令行命令

    rails g controller products index ``` 这会生成一个`products_controller.rb`文件以及对应的视图文件`index.html.erb`。 Rails3还支持安装插件,可以通过以下命令将插件添加到项目中: ```bash rails plugin ...

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

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

    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_email_preview:在Rails中预览和编辑应用程序邮件模板

    Rails电子邮件预览 使用此Rails引擎在浏览器中预览电子邮件。 与Rails 4.2+兼容。 一封电子邮件评论: 所有电子邮件预览的列表: REP带有两个主题:一个简单的独立主题和一个使用的主题。安装加 到Gemfile: gem '...

    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 , ...

    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-...

    rails有用的命令

    - `rails generate controller Say`:生成一个名为“Say”的控制器,包含默认的index、new、create、edit、update、destroy动作。 4. **URL与控制器/动作关联**: - URL `http://rubyonrails.com/say/hello` 中,...

    atom-rails-db-scheme:Rails数据库模式的Autocomplete +提供程序

    Rails数据库方案 Rails数据库模式的Autocomplete +提供程序。 特征 自动完成活动记录 根据当前上下文打开模式文件 设定值 将Rails语法设置为默认语法。 " * " : core : customFileTypes : " source.ruby.rails...

    vite_rails:Rails中的:high_voltage:Vite.js,为您JavaScript体验带来欢乐

    允许您使用为Rails应用程序的前端供电。 是将前端工具像Ruby一样进行编程,纯属喜悦! :smiling_face_with_heart-eyes: 或在运行的检查。 产品特点 :high_voltage: :light_bulb: 即时服务器启动 :high_voltage: ...

    react_rails_flux_screencast:react-rails + Flux(Alt.js)教程

    带有Flux(Alt)的React Rails截屏博客文章: : YouTube视频: : 这是截屏视频的代码,显示了如何将和集成到您的rails应用程序中。 我只使用不带npm的链轮,因此设置非常简单。 Alt( )React Rails( )Lodash( ...

    rails-html-sanitizer

    如果您在非Rails应用程序中需要类似的功能,请考虑直接使用(这是处理内幕消毒的原因)。 安装 将此行添加到您的应用程序的Gemfile中: gem 'rails-html-sanitizer' 然后执行: $ bundle 或将其自己安装为: $...

Global site tag (gtag.js) - Google Analytics