你不知道的Rails console

作者:周星 发布:2015-04-23

       学过一点 Rails 的同学都一定对 console 不陌生,它可以让我们在命令行里和应用程序交互,操作数据库中的数据,还可以在 console 尝试写一点代码来测试自己的思路是否正确等,它是基于 ruby 的 irb 开发的,所以即使你不熟悉 Rails,你也一样可以很快掌握它,今天来给大家分享一些很好用,但是可能鲜为人知的功能。

1. -- sandbox 参数

在执行 Rails console 命令时带上 --sandbox,在我们退出 Rails console 后会自动回滚我们在 console 里执行的数据库操作,这在构造测试数据时非常好用。

2. app

通过 app 对象我们可以与 Rails 应用程序创建一个交互会话,这句话不太容易理解,请执行一下 app.class

irb(main):004:0* app.class
=> ActionDispatch::Integration::Session

这里不会介绍关于 ActionDispatch 的东西,没听说过它并不会影响你写 Rails 程序,但是我鼓励你去探索更多。

想在 console 里看到生成的路由路径?没问题

irb(main):016:0* app.user_path(1)
=> "/users/1"

想模拟一个对应用程序的 get 请求?so easy!

irb(main):035:0* app.get app.messages_path
  User Load (0.2ms)  SELECT `users`.* FROM `users` WHERE `users`.`remember_token` IS NULL LIMIT 1
  Message Load (0.2ms)  SELECT `messages`.* FROM `messages`
   (0.2ms)  SELECT COUNT(count_column) FROM (SELECT 1 AS count_column FROM `messages` LIMIT 10 OFFSET 0) subquery_for_count
  Message Load (0.2ms)  SELECT `messages`.* FROM `messages` ORDER BY id DESC LIMIT 10 OFFSET 0
  User Load (0.2ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
  CACHE (0.0ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
  CACHE (0.0ms)  SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1
# 此处省略后面的日志
=> 200

console 打印了 get 请求 messages_path 路由后的执行日志,并返回了请求的状态码。

然后通过 app.response.header 和 app.response.body 可以看到上次请求的返回头和结果哦。

关于 app 的更多用法,您一定要看 这里这里

3. controller

同样,看看这个 controller 对象是个什么鬼?

irb(main):073:0* controller
=> #<ApplicationController:0x007fde07abcab0 @_routes=nil, @_action_has_layout=true, @_headers={"Content-Type"=>"text/html"}, @_status=200, @_request=nil, @_response=nil>

答案告诉我们,我们可以通过这个对象执行所有 ApplicationController 里的方法,包括我们自定义的和 ActionController::Base 本身的方法,执行一下 controller.methods,去看一下有没有熟悉的身影吧。

假设我们有一个 UsersController,如果我们想调用 UsersController 里的方法怎么办?答案是先 new 一下

irb(main):116:0* UsersController.new.show
NoMethodError: undefined method `parameters' for nil:NilClass

4.helper

如果您从未思考或尝试如何在 console 里调用 helper 方法,那这或多或少可以证明您还只是 Rails 的初级开发者,但是即使您这样做了,也不代表你就告别了初级开发了,好吧,先让我们暂时告别这一段比较绕的逻辑

irb(main):123:0* helper.class
=> ActionView::Base

如上述执行结果所示,您可以通过 helper 对象执行所有的 helper 方法,包括您在 ApplicationHelper 里自定义的和 ActionView::Base 自带的方法,比如生成 html 标签等

irb(main):154:0* helper.truncate("123456", length: 5)
=> "12..."

有的 helper 方法里使用到了参数,我们在 console 调用这个方法时会报错未定义的 params,怎么办怎么办?

def css_option
  if params[:css_option] == "true"
     "css turn on"
  else
     "css turn off"
   end
end

这是因为ActionView 通常需要一个从 controller 中过来的完整的 ActionDispatch::Request,强大的 OpenStruct 可以模仿这一行为:

>> helper.controller = OpenStruct.new(params: {})
=> #<OpenStruct params={}>

>> helper.css_option
=> "css turn off"

>> helper.controller = OpenStruct.new(params: {css_option: "true"})
=> #<OpenStruct params={:css_option=>"true"}>

>> helper.css_option
=> "css turn on"

5. 查看源码?!

当您开始考虑去看一下源码时,说明您已经不是初级开发或者已经走在中高级的道路上了,想查看一下某方法的源码位置,您可以使用 source_location 方法

irb(main):177:0* app.method(:users_path).source_location
=> ["/Users/xingzhou/.rbenv/versions/1.9.3-p125/gemsets/xingishere/gems/actionpack-3.2.13/lib/action_dispatch/routing/route_set.rb", 219]

执行结果清晰的告诉了我们 Rails 路由的源码位置,并且精确到行。

最后:Rails 真的有太多鲜为人知但是却牛逼闪闪的东西,如果您偶然发现了一个,请分享给大家。

如果您对本文有什么意见、建议或者补充,请联系博主。

支付宝扫码赞助博主


评论(0)