+2

Thao tác với rails console - có thể khá thú vị (smile)

Trong quá trình làm việc với Rails console, trước nay tôi cứ nghĩ nó chỉ cho phép test thử những phép toán hoặc method thôi. Ai ngờ đâu, trên console được hỗ trợ rất mạnh mẽ. Ở đây, tôi có tìm hiểu được một số điều hay ho, gọi tắt là mẹo.

Sau đây tôi xin giới thiệu đến các bạn một số mẹo khi thao tác với Rails console mà có thể bạn đã biết rồi :v (thì đừng ném đá mình nhé). Nếu bạn chưa biết thì bắt đầu nào!

1. Rollback sau khi bạn kết thúc 1 session rails console.

Rails cung cấp một môi trường cho phép ta thực hiện điều này, gọi là sandbox. Trong chế độ này, mọi thay đổi đối với database sẽ được tự động rollback khi kết thúc session console.

$ rails console --sandbox

Có thể bạn biết rồi, khi đóng rails console nghĩa là session kết thúc 😄

2. Lấy giá trị của phép thực thi trước đó

Kết qủa của việc thực hiện ngay trước đó trong console có thể được lấy ra, và được gán bằng một biến cục bộ, _. Bằng cách gọi biến này ta sẽ lấy ra được:

>> Product.all.pluck :name 
=> ["test 1", "test 2"]
>> names = _
=> ["test 1", "test 2"]

3. Search methods với grep

Dùng grep để tìm ra tên đầy đủ của một methods từ một phần của nó. Bằng cách gọi grep từ một Array các methods có thể có của một object nhất định.

Ví dụ ta filter methods của một record theo từ khóa pictures

Product.first.methods.grep /pictures/
  Product Load (0.4ms)  SELECT  `products`.* FROM `products` ORDER BY `products`.`id` ASC LIMIT 1
=> [:after_add_for_pictures,
 :after_add_for_pictures?,
 :after_add_for_pictures=,
 :before_remove_for_pictures,
 :before_remove_for_pictures?,
 :before_remove_for_pictures=,
 :after_remove_for_pictures,
 :after_remove_for_pictures?,
 :after_remove_for_pictures=,
 :autosave_associated_records_for_pictures,
 :validate_associated_records_for_pictures,
 :before_add_for_pictures,
 :before_add_for_pictures?,
 :before_add_for_pictures=,
 :pictures,
 :pictures=]

4. Tìm vị trí của một method

Từ console bạn có thể tìm được vị trí của đoạn code một method nào đó, một cách "khá dễ"

Ví dụ, bạn định nghĩa một instance method trong model:

class Product < ApplicationRecord

  def test_name
    name
  end
end

Trong console, bạn muốn biết vị trí mà method được định nghĩa, hãy dùng source_location:

Product.first.method(:test_name).source_location
# Chú ý là Product.first not nil!

Điều này khá hữu dụng khi bạn muốn voc vạch một method nào đó có sẵn trong gem, và muốn debug nó chẳng hạn. Ví dụ như gem sansack nhớ cài gem ransack cho app của bạn trước khi test nhé :v

(ở đây chú ý một điều là ta gọi method ransack bằng class method chứ không phải instance method)

Product.method(:ransackable_attributes).source_location
=> ["#{home_path}/.rbenv/versions/2.5.1/lib/ruby/gems/2.5.0/gems/ransack-2.1.1/lib/ransack/adapters/active_record/base.rb", 35]

Hoặc muốn show luôn code của method ấy ra, cũng dùng tương tự trên, nhưng hãy dùng .source:

Product.method(:ransackable_attributes).source
=> "        def ransackable_attributes(auth_object = nil)\n          @ransackable_attributes ||= if Ransack::SUPPORTS_ATTRIBUTE_ALIAS\n            column_names + _ransackers.keys + _ransack_aliases.keys +\n            attribute_aliases.keys\n          else\n            column_names + _ransackers.keys + _ransack_aliases.keys\n          end\n        end\n"

Cơ mà code được show ra khá thô và khó đọc, vậy nên ta dụng thêm display cho dễ nhìn

pry(main)> Product.method(:ransackable_attributes).source.display
        def ransackable_attributes(auth_object = nil)
          @ransackable_attributes ||= if Ransack::SUPPORTS_ATTRIBUTE_ALIAS
            column_names + _ransackers.keys + _ransack_aliases.keys +
            attribute_aliases.keys
          else
            column_names + _ransackers.keys + _ransack_aliases.keys
          end
        end
=> nil

5. Từ console ta có thể dùng luôn helper để trải nghiệm như trong views

pry(main)> helper.truncate("Test a long string string string string", length: 9)
=> "Test a..."

object helper được include trong rails console, có thể truy cập đến bất kỳ đâu của helper trong ứng dụng hiện tại của bạn. Bạn chẳng cần phải bật server và nhảy vào debug trong helper hoặc ở tận màn hình views mới có thể được source code của mình.

"Khá tiện".

6. Rails console cũng cấp cho chúng ta object app

app ở đây chính là instance project hiện tại của bạn, từ object này bạn có thể gọi một HTTP request như khi đang chạy rails server vậy. Kiểm chứng nhé

 app
=> #<ActionDispatch::Integration::Session:0x00005638cdd72128
 @_mock_session=nil,
 @_routes=nil,
 @accept="text/xml,application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5",
 @app=
  #<XXX::Application:0x00005638cc6e56a8
   @_all_autoload_paths=
... # too long, no display.

và gọi một HTTP request:

 pry(main)> app.get("/")
Started GET "/" for 127.0.0.1 at 2019-01-01 09:22:55 +0700
   (0.3ms)  SELECT `schema_migrations`.`version` FROM `schema_migrations` ORDER BY `schema_migrations`.`version` ASC
Processing by ProductsController#index as HTML
  Rendering products/index.html.erb within layouts/application
  Product Load (0.4ms)  SELECT  DISTINCT `products`.* FROM `products` LIMIT 25 OFFSET 0
  Rendered collection of products/_product.html.erb [1 times] (42.7ms)
  Rendered products/index.html.erb within layouts/application (59.2ms)
Completed 200 OK in 750ms (Views: 735.0ms | ActiveRecord: 1.7ms)


=> 200

Hoặc dùng luôn grep để tìm những link support cho một class nào đó (cái này thì chỉ là thêm thôi, vì mình thường dùng rake routes | grep xxx thì đơn giản hơn rồi)

app.methods.grep(/path/).grep /product/
=> [:shop_products_path,
 :new_shop_product_path,
 :edit_shop_product_path,
 :products_path,
 :new_product_path,
 :product_path,
 :edit_product_path,
 :shop_product_path]

Hoặc gọi ra app.body, app.cookies của project hiện tại:

pry(main)> app.cookies
=> #<Rack::Test::CookieJar:0x00007efe108e8040
@cookies=
[#<Rack::Test::Cookie:0x00005638cf380618
  @default_host="www.example.com",
  @name="_xxx_session",
  @name_value_raw=
   "_xxx_session=QzcvNzhxS0prdzlmWlFYM0NMb0Q4cU00dFppd3dUai85dnFwdE5ua1ZjZmJSejIvbS9zbEQraGxMOUlPeVdwdXZXYmdJQXgrei8wU2NKajR3S1BFOGh3MnlNbDFsTGhWVUVHcURDV2lSRFc3Z1BNa1AxU3pkR3pmOEhkSzFCYVB6QlE1OWplbm5hMTBIS3JCS2E3dTNnPT0tLUtPOTJxUHpjVnMyaHhTbklDYlk4bVE9PQ%3D%3D--41c211c9bf6297f9b0014da946fe1be04e929548",
  @options={"path"=>"/", "HttpOnly"=>nil, "domain"=>"www.example.com"},
  @value=
   "QzcvNzhxS0prdzlmWlFYM0NMb0Q4cU00dFppd3dUai85dnFwdE5ua1ZjZmJSejIvbS9zbEQraGxMOUlPeVdwdXZXYmdJQXgrei8wU2NKajR3S1BFOGh3MnlNbDFsTGhWVUVHcURDV2lSRFc3Z1BNa1AxU3pkR3pmOEhkSzFCYVB6QlE1OWplbm5hMTBIS3JCS2E3dTNnPT0tLUtPOTJxUHpjVnMyaHhTbklDYlk4bVE9PQ==--41c211c9bf6297f9b0014da946fe1be04e929548">],
@default_host="www.example.com">

7. Kết luận

Trên đây là một số mẹo mình cho là "Khá thú vị" mà mình có tìm hiểu được khi thao tác với Rails console, mình mong rằng sẽ đem đến cho bạn một số trải nghiệm và tiện ích. Chúc mừng năm mới! Thân.


All rights reserved

Viblo
Hãy đăng ký một tài khoản Viblo để nhận được nhiều bài viết thú vị hơn.
Đăng kí