前面的章节主要关注通过服务器与用户交互的场景。但不是所有 web 交互都有人参与。本章关注访问 Rails 应用和来自独立运行脚本的数据。
下面列举了几点关于我们想在浏览器外部访问 Rails 应用的原因。比如,你需要单独操作数据库,或者使用类似 cron
的后台定时异步任务工具的场景。可能你已经拥有了 Rails 应用,并且想通过另一个 Rails 应用直接访问数据,它们可能部署在不同的机器上。首先想到的可能是命令行接口,无论它是否真的需要。
不管何种原因,Rails 已经为你准备好。如你所见,Rails 可以为你完成大量的工作。
我们先假设你的应用和数据都存放在同一台机器上,然后再讲述如何在远程机器上完成同样的工作。
使用 Active Record 的独立应用
你最想访问的应该是数据。即使是独立运行你也依然可以使用 Active Record。我们先向你展示完成此事的困难模式(尽管如此它也不会太过困难,毕竟我们还是在基于 Rails 讨论问题),然后再体验简易模式。
一开始我们要处理通过 Active Record 处理 SQLite 3 中 orders 表的独立运行程序。通过指定 id
查找到订单数据后要修改买家的名字,并将结果存储回数据库,然后更新原来的数据记录。
require "active_record"
ActiveRecord::Base.establish_connection(adapter: "sqlite3",
database: "db/development.sqlite3")
class Order < ActiveRecord::Base
end
order = Order.find(1)
order.name = "Dave Thomas"
order.save
上述就是所有的代码了,其中并不需要任何配置(除了数据库连接信息外)。Active Record 知道我们关于数据库的述求及我们关注的细节。
在看过困难模式后来了解一下简易模式,Rails 会为你管理链接并加载相应的 model。
require "config/environment.rb"
order = Order.find(1)
order.name = "Dave Thomas"
order.save
为了正常运转,Ruby 需要加载 config/environment.rb
文件,你可以通过引用声明文件路径,也可以在 RUBYLIB
环境变量中设置路径。通过 RAILS_ENV
可以了解其他环境变量,其中包括开发、测试和生产环境。
一旦我们引入了环境文件,便可以像 205 页中使用 rails console
一样 Rails。
只要引入一个文件就可以使用所有功能,难道还不简单吗?无论你信不信,其实你在 Rails 外只是想使用其中的一部分功能。接下来我们将学习如何使用其中一部分功能。
使用 Active Support 的库函数
Active Support 是一组 Rails 组件的共享库。有一些是为了在 Rails 中使用,不过也可以在非 Rails 的应用中使用。
如果你开发了一个 Rails 应用,并在其中使用了一组类,甚至是一组方法,而此时你想在非 Rails 应用中使用它,这点就十分重要。你可能想将代码拷贝粘贴到其他的文件中,结果发现它并不能正常运行,并不是因为应用中的逻辑互相依赖,而是由于它使用了 Rails 提供的类和方法。
我们会简洁地介绍其中最重要的部分,并演示如何在你的应用中运转。
核心扩展
Active Support 扩展了一些 Ruby 现成的类,使其更加有用。在本节中,我们要快速浏览这些核心扩展中最受欢迎的部分。
-
Array:
second()
、third()
、fourth()
、fifth()
和forty_two()
。这些方法是为了补充 Ruby 提供的first()
和last()
方法。 -
CGI:
escape_skipping_slashes()
。它与escape()
方法的不同之外在于会跳过斜杠。 -
Class:类属性访问器方法、委派访问器方法、可继承的读取器和写入器、及后裔(也就是子类)。这些方法太多就不一一列举,有兴趣可以查看文档。
-
Date:
yesterday()
、future?()
、next_month()
及其他方法。 -
Enumerable:
group_by()
、sum()
、each_with_object()
、index_by()
、many?()
和exclude?()
。 -
File:
atomic_write()
和path()
。 -
Float:为
round()
方法增加了precision
参数。 -
Hash:
deep_merge()
、except()
、stringify_keys()
、symbolize_keys()
、reverse_merge()
和slice()
。这些方法中还有许多以感叹号结尾的变量。 -
Integer:
ordinalize()
、multiple_of?()
、months()
、years()
。也可以参考 Numberic。 -
Kernel:
debugger()
、breakpoint()
、silence_warmings()
、enable_warnings()
。 -
Module:model 属性的访问器方法、别名支持、委派、deprecation、内部读取器和写入器、异步和百分比。
-
Numeric:
byte()
、kilobytes()
、megabytes()
等等,seconds()
、minutes()
、hours()
等等。 -
Object:
blank?()
、present?()
、duplicable?()
、instance_values()
、instance_variable_()names()
、returning()
和try()
。 -
String:
exclude?()
、pluralize()
、sigularize()
、camelize()
、titleize()
、underscore()
、dasherize()
、demodulize()
、parameterize()
、tableize()
、classify()
、humanize()
、foreign_key()
、constantize()
、squish()
、mb_chars()
、at?()
、from()
、to()
、first()
、last()
、to_time()
、to_date()
和try()
。 -
Time:
yesterday()
、future?()
、advance()
和许多其他的方法。
我们已经列举了很长一串方法。这些方法都不大,甚至许多都只有一行代码。尽管你只会使用其中的一小部分,但列举的所有方法在 Rails 应用中都可以使用。
虽然已经列举了很多方法,但其中的大部分你并不会直接使用。不过你很快就会在 Ruby 代码中采纳一部分扩展方法。虽然所有的方法都可以通过在线文档学习,但最好的方法还是直接在 rails console
中体验。你可以体验一下下面的代码:
2.years.ago
[1,2,3,4].sum
5.gigabytes
"man".pluralize
String.methods.sort
因为还没有方法能够完全保证扩展方法正常,所以在使用时要小心确认,当你需要某个扩展方法中未提供的功能时最好查看一下在线文档,可能拥有同样需求的开发人员已经扩展了相应方法。
其他 Active Support 类
除了上述对方法的扩展 Active Support 还对 Ruby 基本对象进行了扩展。Active Record 提供了许多新增的函数,这些对核心的扩展还是为了支持 Rails 组件的需求,但你也可以直接使用它们。
-
Benchmarable:测算模板中 block 执行的时长并将结果记录在日志中。
-
Cache::Store:提供了多种缓存实现,有基于文件的也有基于内存的,并且还有同步和压缩选项。
-
Callbacks:在对象生命周期中提供钩子。
-
Concern 和 Dependencies:分模块管理依赖。
-
Configurable:提供
Hash
类变量的配置 -
Deprecation:提供对失效方法的行为、报告和封装的支持。
-
Duration:提供新增方法,比如
ago()
和since()
。 -
Gzip:提供方便的方法
compress()
和decompress()
压缩和解压字符串。 -
HashWithIndifferentAccess:
params[:key]
和parmas['key']
都可以访问。 -
I18n:提供国际化支持。
-
Inflections:处理英语的复数形式。
-
JSON:提供 JavaScript Object Notation 编码及解码方法。
-
LazyLoadHooks:提供推迟 module 初始化的支持。
-
MessageEncryptor:加密可以存放于不安全地方的数据。
-
MessageVerifier:生成和验证签名信息(防止被干预)。
-
MultiByte:提供编码支持(从 Ruby 1.8.7 开始支持)。
-
Notifications:提供仪表化的 API。
-
OptionMerger:提供深层合并的 lambda 表达式。
-
OrderedHash 和 OrderedOptions:提供有序哈希支持(从 Ruby 1.8.7 开始支持)。
-
Railtie:定义框架依赖的其余核心对象。
-
Rescueable:简化异常处理。
-
StringInquier:提供更好的方式比较相等。
-
TestCase:提供许多方法,使能够在安全的沙盒中测试 rubygems 和 gems 相关行为。
-
Time 和 TimeWithZone:提供计算和转换的支持。
David 提问:为何扩展基类没有导致灾难
当第一次处理
5.months + 30.minutes
时大家都会感到慌乱。如果每个人都对整型数据的功能进行了修改,必将导致无尽的混乱。但现在并不是每个人都在扩展基类,所以混乱的局面并不会出现。不要将 Active Support 视为一组对 Ruby 的随机扩展,你要将它视为 Rails 程序员使用的 Ruby 方言。因为 Active Support 是 Rails 的一部分,
5.months
也可以一直在 Rails 应用中正常运行。通过此观点即可否决掉有许多定制的 Ruby 方言的问题。Active Support 作为语言的扩展时会为我们带来许多便利。毕竟它只是基于某种环境的标准。
如果你和许多人一样依赖这些扩展,你可以按需引入(比如,require "active_support/basic_object"
或 require "active_support/core_ext"
)或者全部引入 require "active_support/all"
。
使用 Action View 辅助方法
尽管无法减少 Active Support 的分类,但它还是比较封闭的。Active Support 也可以应用在 Rails 的其他方面,虽然路由、controller 和 Action View 与 web 请求紧密相关。
要注意的地方是 Action View 的辅助类。下面的例子展示了如何在独立运行的应用中访问 Active View 辅助方法:
require "action_view"
require "action_view/helpers"
include ActionView::Helpers::DateHelper
puts distance_of_time_in_words_to_now(Time.parse("December 25"))
虽然它比直接使用 Active Support 需要编写更多代码,但也能实现功能。
总结
最后,我们从浏览器的限制从脱离了出来,并且依然能在独立运行的应用中使用 Active Support、Action View 和 Active Record。这赋予了我们编写运行命令行脚本的能力,然后集成于当前应用中,或定时运行自动调用类似 cron
的工具。
接着,我们要探索其他 Rails 携带的部分组件。
本文翻译自《Agile Web Development with Rails 4》,目的为学习所用,如有转载请注明出处。
网友评论