มีหลายวิธี launch Ruby/Rails console: irb, bundle exec irb, bundle console, rails console ดูคล้ายกัน แตทำงานต่างกันนิดหน่อย
ถ้าไม่รู้ความต่าง จะมีปัญหา อาจเชื่อม ActiveRecord models กับ database ไม่ได้ หรือ require file ได้ version ผิด หรือ library ที่คิดว่ามี จริงๆ แล้วไม่มี
ทำยังไงให้แน่ใจว่าใช้ console ถูกต้องตอนที่ถูกต้อง?
Bundler vs non-Bundler
irb คือ plain Ruby console ไม่สนใจ Gemfile โหลดแค่ core Ruby libraries อะไรอยากได้ ต้อง require เอง
ติดตั้ง gem ด้วย gem install require ใน irb ได้ ถ้า bundle install อาจ require ได้ ขึ้นอยู่กับ Bundler วางไว้ไหน (Bundler วาง gems นอก Ruby gem path บางครั้ง ถ้า bundle install --path หรือ --deployment)
เพราะ irb ไม่สน Gemfile versions ใน Gemfile.lock ไม่มีผล irb โหลด version ใหม่สุดที่หาเจอ:
~/Source/testapps/consoles[master *] jweiss$ gem list rails *** LOCAL GEMS *** rails (4.2.0.beta2, 4.2.0.beta1, 4.1.5, 4.1.1) ~/Source/testapps/consoles jweiss$ cat Gemfile | grep rails gem 'rails', '4.1.5' ~/Source/testapps/consoles jweiss$ irb irb(main):001:0> require 'rails' => true irb(main):002:0> Rails.version => "4.2.0.beta2" ทำให้ปัญหาแปลกๆ กับโค้ด ถ้าไม่คาดคิด
irb ดีสำหรับเล่น core Ruby files เร็ว ไม่ต้อง setup
แต่ถ้าอยากใช้ Gemfile ตอนรัน console ให้รัน bundle exec irb แทน bundle exec ให้ irb โหลด gems ที่ Bundler รู้ และ แค่ gems ที่ Bundler รู้:
~/Source/testapps/consoles jweiss$ bundle exec irb irb(main):001:0> require 'rails' => true irb(main):002:0> Rails.version => "4.1.5" ได้ Rails version ที่ต้องการพอดี
bundler/setup vs Bundler.require
รัน bundle console แทน bundle exec irb เมื่อไหร่?
bundle exec irb setup ให้ require gems ใน Gemfile.lock ได้อย่างเดียว
bundle console ไปอีกขั้น ตอนรัน bundle console ไม่ต้อง require gems ใน Gemfile แล้ว มัน require ให้หมด:
~/Source/testapps/consoles jweiss$ bundle exec irb irb(main):001:0> Rails.version NameError: uninitialized constant Rails from (irb):1 from /usr/local/bin/irb:11:in `<main>' ~/Source/testapps/consoles jweiss$ bundle console irb(main):001:0> Rails.version => "4.1.5" พฤติกรรมนี้ได้จากการเรียก Bundler.require ใน bundle exec irb console ด้วย Gem ใน Gemfile ที่ไม่ marked require: false จะ auto-required ใช้ได้เลยโดยไม่ต้อง require เพิ่ม ตอนทำงาน projects ที่มี Gemfile สะดวกมาก
เข้าถึง Rails
ยังมีความต่างอีก: bundle console และ rails console
~/Source/testapps/consoles jweiss$ bundle console irb(main):001:0> Rails.application => nil ~/Source/testapps/consoles jweiss$ rails console Loading development environment (Rails 4.1.5) irb(main):001:0> Rails.application => #<Consoles::Application:0x007f8db4d5ab30 @_all_autoload_paths=["/Users/jweiss... bundle console แค่ require gems มากๆ rails console require gems นั้น แต่ยัง load ทั้ง Rails environment, setup autoloading, initialize application, และให้ full Rails environment เล่น
ได้แบบ Rails console จาก bundle console ถ้า require config/environment.rb:
~/Source/testapps/consoles jweiss$ bundle console irb(main):001:0> Rails.application => nil irb(main):002:0> require_relative 'config/environment.rb' => true irb(main):003:0> Rails.application => #<Consoles::Application:0x007fd264f0b7c8 @_all_autoload_paths=["/Users/jweiss... แต่ละอัน ซับซ้อนขึ้นนิดหน่อย
สรุป:
-
irbbasic Ruby console ไม่สน Gemfile มีแค่ core Ruby classes โดยไม่ต้อง require ไม่โหลด gems ที่ Bundler วางนอก RubyGems load path ได้ง่าย -
bundle exec irbเหมือนirbถ้า requirebundler/setupด้วย require gems ใน Gemfile.lock ได้ แตโหลด gems นั้นได้ ไม่ว่าจะวางไหน -
bundle consoleเหมือนbundle exec irbถ้าเรียกBundler.requireด้วย Gems ใน Gemfile (ยกเว้นrequire: false) ใช้ได้เลยโดยไม่ require สะดวกมากตอนเขียน gems หรือ non-Rails code -
rails consoleเหมือนรันbundle consoleใน Rails app ถ้า requireconfig/environment.rbด้วย เล่นกับทั้งแอป Rails autoloads และ database connections ทำงาน ทุกอย่าง hooked up ตามที่คาด หากทำงานใน Rails app นี่ console ที่ช่วยมากที่สุด
ความต่างไม่มาก แตบางอย่างไม่ใหญ่ (Oh file นี้ไม่ required? require ใหม่ซิ!) บางอย่างน่าหงุดหงิดมากถ้าไม่รู้ (WHY WRONG RAKE VERSION AGAIN!?)
แตถ้ารู้ concept แต่ละ console จะใช้ console ที่ถูกต้องตอนที่ถูกต้อง และ libraries ที่ต้องการจะอยู่ใกล้มือตอนต้องการ