Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Ruby

Giải mã Ruby Gem: Cách chúng hoạt động và tại sao quan trọng

Điều làm Rails dễ dùng: mọi nhu cầu lập trình phổ biến — authorization, site admin, ecommerce — ai đó thông minh hơn đã code giải pháp và gói thành gem.

Bạn có thể add gem vào Gemfile tận hưởng dùng mà không hiểu thực sự cách chúng hoạt động. Nhưng bạn có tò mò cách mọi thứ được "wired up"?

Ở đây xem kỹ gem CanCan authorization của Ryan Bates và trả lời (nếu hỏi rộng hơn, áp dụng cho bất kỳ gem nào):

  1. Code CanCan được lưu ở đâu?
  2. Method `can?` định nghĩa ở đâu?
  3. Khi/đâu/như thế nào Rails load code CanCan?

Trước tiên, có CanCan trong Gemfile, chạy `bundle install`:

# Gemfile
gem "cancan", "~> 1.6.10"
$ bundle install

Với Bundler, dễ dàng xem gem nào ở đâu. Dùng `bundle show`:

$ bundle show cancan
/Users/jasonswett/.rvm/gems/ruby-2.0.0-p0/gems/cancan-1.6.10
Đây trả lời câu #1. Bây giờ `can?` ở đâu?

$ cd /Users/jasonswett/.rvm/gems/ruby-2.0.0-p0/gems/cancan-1.6.10
$ grep -r 'def can?' *
lib/cancan/ability.rb: def can?(action, subject, *extra_args)
lib/cancan/controller_additions.rb: def can?(*args)

Có vẻ 2 function `can?` khác nhau. Cái chúng ta quan tâm ở `lib/cancan/ability.rb`.

# lib/cancan/ability.rb
def can?(action, subject, *extra_args)
  match = relevant_rules_for_match(action, subject).detect do |rule|
    rule.matches_conditions?(action, subject, extra_args)
  end
  match ? match.base_behavior : false
end

Cái gì thực sự xảy ra ở đây, đoán của bạn cũng ngang ngửa tôi, nhưng không phải phần quan trọng. Takeaway: nếu gặp vấn đề với gem, bạn giờ equipped để đào vào code gem tìm hiểu.

Biết gem code ở đâu và cách vào, làm sao Rails biết gem, và khi nào load code gem?

Được cover ở section Rails initialization docs. Phần liên quan:

Trong Rails app chuẩn, có Gemfile khai báo mọi dependency. config/boot.rb set ENV['BUNDLE_GEMFILE'] đến file này. Nếu Gemfile tồn tại, bundler/setup được require.

Xảy ra sớm trong initialization: bước 2, chính xác. Hợp lý vì nếu project depend gem, ai biết bạn reference nó đâu. Load sớm nhất để code dùng được mọi nơi.