`

Rails Metal指南

阅读更多
今天在Metal中用到了读取当前登录用户current_user的方法,于是找到了下面这篇文章,虽然是09年的,但是价值依旧在,翻译一下,以备后用

Rails Metal使用指南

Posted by mikong on February 03, 2009

    当我在使用Rails Metal写程序的时,才发现我已经被Rails带来的便利所宠坏了,没有了controller和view helpers,简直太痛苦了。希望这个指南能给您带来更好的体验。
    在这个指南中,我们会写一个Widget Refresher Metal的小程序,假设我们的rails工程中的widget页面访问次数非常多,并且我们想充分发挥使用Metal的优势。那么在我们的工程的 app/metal 目录下,创建 refresher.rb

  
  class Refresher < Rails::Rack::Metal
    def self.call(env)
      refresher = RefresherApp.new
      refresher.call(env)
    end
  end

  class RefresherApp
    def call(env)
      # refresh widget path: /widgets/:id/refresh
      if env["PATH_INFO"] =~ /^\/widgets\/(\d+)\/refresh/
        widget_id = $1
        prepare(env, widget_id)
        refresh
      else
        [404, { "Content-Type" => "text/html" }, "Not Found"]
      end
    end

    # to setup the environment
    def prepare(env, widget_id)
      ...
    end

    # the heart of our Metal app
    def refresh
      ...
    end
  end


相比较把所有的代码都写在Refresher类(继承自Rails::Rack::Metal)里面,我更喜欢创建一个单独的RefresherApp类。当你的Metal程序已经不再是平凡简单的HelloWorld的时候,需要一大串相互调用的方法, 因为这个call方法在这个Metal程序中是一个类方法,把所有的代码放在一个类里面将意味着所有的这些方法都将是一些类方法。但是我觉得那样太丑陋了。如果你想,尽管把这些代码放在一个类里面。如果真的打算这么做,你可以设置上下文为self的,这样就没有必要在每一个方法前面加一个“self.”了。
  class Refresher < Rails::Rack::Metal

    # the methods in here are class methods
    class << self
      def call(env)
        ...
      end

      def method
        ...
      end
    end

  end


另外,在开发Metal程序的时候需要注意,为确保你的代码变化生效你需要持续的重启你的服务。.

Request和Session

你可以通过下面这些代码,访问request以及它里面的参数

request = Rack::Request.new(env)
params = request.params
params['mykey'] # String keys, so not params[:mykey]


正如你所看到的,这些 keys 是字符串实例,而不是Symbol。
对于session则可以这样得到

session = env['rack.session']


你可以吧所有的这些代码一移动到prepare方法中。此外,我们可以设置params[:id](如果你愿意你可以使用Symbol),我们的主refresh方法中,看起来像是一个rails的controller。通过session我们可以得到当前用户。同样我们可以像在rails controller中写方法一样去定义其他方法。正如下面所示:

  attr_reader :request, :session, :current_user

  def params
    @request.params
  end

  def logged_in?
    !!current_user
  end

  def prepare(env, widget_id)
    @request = Rack::Request.new(env)
    params[:id] = widget_id
    @session = env["rack.session"]
    @current_user = session[:user_id] ? User.find(session[:user_id]) : false
  end



做了这些准备工作,我们可以开始写这个叫做refresh的主方法了

refresh 和 ActiveRecord

假设,在客户端,我们只需要返回widget 的status属性
  def refresh
    @widget = Widget.find(params[:id])

    return [200, { "Content-Type" => "text/html" }, @widget.status]
  end

只要确保格式正确,你同样可以给客户端返回javascript或者其他类型的内容。另外可以添加简单的检查用户是否登录的校验
  def refresh
    @widget = Widget.find(params[:id])

    if logged_in?
      return [200, { "Content-Type" => "text/javascript" }, "Element.update('status', '#{@widget.status}');"]
    else
      return [200, { "Content-Type" => "text/javascript" }, "Element.update('message', 'Must be logged in for widget status to refresh');"]
    end
  end


但是在返回一个比较复杂的javascript的时候,最好还是避免回车和引号,否则在浏览器这边我们会解析错误,rails提供了一个叫做escape_javascript的方法,但是Metal程序中默认情况下是不能访问的。

View Helpers

要想在Metal程序中使用helper,只需要引用(include)你所需要的modules的就可以了
  include ActionView::Helpers::JavascriptHelper # so escape_javascript works
  include WidgetsHelper # for example

但是我更倾向于避免使用这些帮助方法

Request Forgery Protection
伪请求防护

如果不是get请求的request,你需要辨别authenticity token的真假

可以实现的一种方法:
  def refresh
    # before everything else
    return redirect_to_widgets_response unless verified_request?

    # everything else
    ...
  end

  def redirect_to_widgets_response
    return [302, { "Content-Type" => "text/html", "Location" => "/widgets" },
      "<html><body><a href=\"/widgets\">Redirecting...</a></body></html>"]
  end

  # Based on Rails method of the same name but simplified, i.e. no need to check if:
  #   - protection is disabled
  #   - request method is :post
  #   - format is verifiable
  def verified_request?
    form_authenticity_token == params['authenticity_token']
  end

  def form_authenticity_token
    session[:_csrf_token] ||= ActiveSupport::SecureRandom.base64(32)
  end

更多的挑战

在写自己的Rail Metal程序的时候,你可能会遇到其他的一些挑战,我已经尝试直接使用ERB来渲染一个模板,但感觉还是不要在这里献丑了。但是我已经尽力了。不是所有的业务逻辑可以这么快的专程Metal程序。简单的事情建议这么做,否则就太得不偿失了。不管怎样,希望这篇指南可以帮你解决一些问题。当然,如果你有什么好的建议可以提。

------------
欢迎指正建议,谢谢

原文地址
http://devblog.michaelgalero.com/2009/02/03/guide-to-rails-metal/
分享到:
评论

相关推荐

    Ruby On Rails 官方指南

    原文在此http://guides.ruby-china.org/index.html 我只是把html拷贝到word里面罢了 然而只拷贝到了Rails 安全指南这一章,后面的太多就没拷贝了 初学者只需打印到368页即可

    Ruby on Rails安装指南(Ruby 1.8.6+Rails 2.0.2)

    Ruby on Rails 安装指南 Ruby on Rails 安装指南是指安装 Ruby 1.8.6 和 Rails 2.0.2 的详细步骤。首先,需要下载 Ruby One-Click Installer 版本,并安装 Ruby。然后,下载 Rails 2.0.2 版本,并安装。接下来,...

    Ruby on Rails中文指南

    在Ruby on Rails中文指南中,你将全面学习到如何利用这个强大的框架来构建动态的、数据驱动的Web应用程序。 首先,让我们深入理解Rails的核心概念: 1. **路由(Routes)**:Rails的路由系统是应用程序的导航蓝图...

    rails指南 中文版

    Rails指南中文版是针对Ruby on Rails框架的一份详尽教程,旨在帮助开发者深入理解并熟练掌握这个强大的Web应用开发工具。Ruby on Rails(简称Rails)是一个基于Ruby语言的开源Web应用框架,它遵循MVC(Model-View-...

    Ruby on Rails 指南 v5.0.1 中文版

    ### Ruby on Rails 指南 v5.0.1 中文版 #### Rails入门 - **前提条件**:为了能够顺利地开始Rails的学习之旅,读者需要具备一定的Ruby语言基础,并且对Web开发有一定的了解。 - **Rails是什么?**:Rails是一种...

    rails框架指南.pdf

    Ruby on Rails是一个开源的全栈web应用框架,它基于Ruby编程语言,由David Heinemeier Hansson创建,并遵循MVC(Model-View-Controller)设计模式。它的主要设计理念是“约定优于配置”(Convention over ...

    Ruby on Rails安装指南.docx

    《Ruby on Rails安装指南》是一份详尽的文档,旨在帮助用户在不同的环境下安装和配置Ruby on Rails开发环境。这份指南适用于使用Ruby 1.8.6和Rails 2.0.2版本的用户,虽然这些版本可能相对较旧,但其安装流程对于...

    Ruby on Rails开发指南

    本指南将深入介绍Ruby on Rails的核心概念、开发环境的搭建以及实际项目中的应用。 1. **Ruby语言基础**:Ruby是Rails的基础,它是一门动态类型、面向对象的语言,以其简洁、优雅的语法而著名。理解Ruby的基本数据...

    rails3入门指南

    ruby on rails文档,rails3入门指南

    Rails 指南

    Rails 指南

    semantic-ui-sass, 转换为Sass并准备放入 Rails &指南中的语义 UI.zip

    semantic-ui-sass, 转换为Sass并准备放入 Rails &指南中的语义 UI 用于Sass的语义 UIsemantic-ui-sass 是一个sass的语义UI插件,可以将它的放到。Compass或者链轮中。 注释gem 只有默认主题。安装和使用gem '...

    Agile Web Development with Rails 4th edition(敏捷Web开发与Rails:程序指南 第四版)

    《敏捷Web开发与Rails:程序指南 第四版》是一本深度探讨使用Ruby on Rails框架进行敏捷Web应用开发的专业书籍。本书旨在帮助开发者充分利用Rails 4的特性,提高开发效率,实现快速迭代和高质量的代码编写。 Rails是...

    rails-style-guide:社区驱动的Ruby on Rails样式指南

    Rails样式指南榜样很重要。 -军官Alex J. Murphy / RoboCop 小费您可以在找到本指南的精美版本,并对其导航进行了改进。 本指南的目的是为Ruby on Rails 4开发提供一组最佳实践和样式说明。 它是对现有社区驱动的的...

    Ruby on Rails 4.0指南:学习Ruby on Rails 4.0和Ruby 2.0的分步指南Ruby on Rails 4.0 Guide: A step by step guide to learn Ruby on Rails 4.0 and Ruby 2.0

    学习Ruby on Rails 4.0的逐步指南。 它包括针对Ruby 2.0.0的基本教程,是为至少了解另一种编程语言并熟悉HTML的程序员编写的。

    社区驱动的Ruby on Rails样式指南-Ruby开发

    Rails样式指南简介角色模型很重要。 —官员Alex J. Murphy / RoboCop提示《 Rails样式指南》简介榜样很重要。 —官员Alex J. Murphy / RoboCop提示您可以在https://rails.rubystyle.guide上找到本指南的精美版本,并...

    rails2-sample

    本书旨在为初学者提供深入理解Ruby on Rails框架的指南,从基础概念到高级主题均有涵盖,是学习Ruby on Rails的理想选择。 ### 重要知识点概览 #### 1. Introducing Ruby on Rails(介绍Ruby on Rails) 这一章节...

    ruby on rails guides v5.0.0.1

    ruby on rails 开发指南

    Rails101_by_rails4.0

    《Rails101_by_rails4.0》是一本专注于Rails 4.0.0版本和Ruby 2.0.0版本的自学教程书籍,它定位于中文读者,旨在成为学习Rails框架的参考教材。Rails(Ruby on Rails)是一个采用Ruby语言编写的开源Web应用框架,它...

Global site tag (gtag.js) - Google Analytics