Thao tác với rails console - có thể khá thú vị (smile)
Bài đăng này đã không được cập nhật trong 5 năm
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