2015-04-28 14 views
8

Tôi khá mới với ruby, đến từ một nền tảng php, nhưng một cái gì đó không phải là nhấp với tôi.Ruby namespacing

Vì vậy, chúng ta hãy nói rằng tôi có một Ruby on ứng dụng Rails và tôi versioning API của tôi như vậy:

app 
|_controllers 
    |_api 
    | |_v1 
    | | |_application_controller.rb 
    | | |_user_controller.rb 
    | |_application_controller.rb 
    |_application_controller.rb 

Với cấu trúc lớp với

# Versioned API V1 app controller 
module Api 
    module V1 
    class ApplicationController 
    end 
    end 
end 

# Versioned API app controller 
module Api 
    class ApplicationController 
    end 
end 

# Root app controller 
class ApplicationController 
end 

#The code in question 
module Api 
    module V1 
    class UserController < ApplicationController 
    end 
    end 
end 

Vì vậy, câu hỏi là, làm ruby tìm kiếm Api::V1::ApplicationController, Api::ApplicationController hoặc ApllicationController để mở rộng?

Có phải < ApplicationController tìm kiếm không gian tên riêng của nó trừ khi tôi chỉ định Api::ApplicationController? Nếu có, làm cách nào để chỉ định thư mục gốc?

Trả lời

16

Khi bạn sử dụng

#The code in question 
module Api 
    module V1 
    class UserController < ApplicationController 
    end 
    end 
end 

ApplicationController định nghĩa sẽ được tìm kiếm trong Api::V1 sau đó nếu không tìm thấy trong Api sau đó nếu không tìm thấy trong namespace root.

Tôi đồng ý nó có thể là khó hiểu, đó là lý do tại sao tôi có xu hướng sử dụng đường dẫn tuyệt đối như vậy: ::ApplicationController

Nếu bao giờ tôi cần Api::ApplicationController, tôi muốn viết ::Api::ApplicationController

Về cơ bản các :: nói với ruby ​​để bắt đầu từ không gian tên gốc và không phải từ nơi mã tồn tại.


Sidenote

Hãy nhận biết rằng có những trường hợp luẩn quẩn trong chế độ phát triển Rails. Để đạt được tốc độ, mức tối thiểu nghiêm ngặt được tải. Sau đó, Rails tìm kiếm các định nghĩa lớp khi cần.

Nhưng điều này đôi khi thất bại ví dụ thời gian lớn, khi bạn đã nói ::User đã được tải, và sau đó tìm kiếm ::Admin::User. Rails sẽ không tìm kiếm nó, nó sẽ nghĩ rằng ::User hiện các trick.

Điều này có thể được giải quyết bằng cách sử dụng các câu lệnh require_dependency trong mã của bạn. Tốc độ có chi phí :)

+0

Cảm ơn bạn, điều này đã xóa bỏ sự nhầm lẫn tôi đã có. – GingerTech

+0

mát mẻ :) khó hiểu nhất là khi bạn gặp phải các vấn đề như mô tả trong sidenotes của tôi – apneadiving

+0

thú vị, tôi nghĩ rằng sidenote của bạn xóa vấn đề tôi đã có [ở đây] (http://stackoverflow.com/questions/29849501/object -const-get-and-rails-cắt-off-cha-đun-tên) – dax

0

Bạn nên kiểm tra hướng dẫn để hiểu được định tuyến: http://guides.rubyonrails.org/routing.html#controller-namespaces-and-routing

Tôi nghĩ rằng câu hỏi này là rất tương tự như:

Rails Controller Namespace

Và như thiếu:

Rails sẽ tự động phát hiện không gian tên theo thư mục.Vì vậy, bạn không cần phải thêm nó vào tên:

bài

Blog này giải thích nó rất tốt:

http://blog.makandra.com/2014/12/organizing-large-rails-projects-with-namespaces/

Hãy nói rằng chúng ta có một lớp hóa đơn và mỗi hóa đơn có thể có nhiều mục hóa đơn:

class Invoice < ActiveRecord::Base 
    has_many :items 
end 

class Item < ActiveRecord::Base 
    belongs_to :invoice 
end 

rõ ràng Invoice là một thành phần của mục và một khoản không thể sống 012.không có hóa đơn có chứa. Các lớp học khác có thể sẽ tương thích với Invoice chứ không phải với Item. Vì vậy, hãy lấy Item ra khỏi cách bằng cách lồng nó vào không gian tên Invoice. Điều này bao gồm đổi tên lớp để INVOICE :: Item và di chuyển các tập tin nguồn để app/models/hóa đơn/item.rb:

class Invoice::Item < ActiveRecord::Base 
    belongs_to :invoice 
end 

Cùng được áp dụng cho các bộ điều khiển và quan điểm.

2

Tôi thà đề nghị không viết ApplicationController trong không gian tên, tôi sẽ đề nghị đi theo sau

Lưu ý: Nếu bạn đang xây dựng chuyên nghiệp api của nó luôn luôn tốt để có Api::V1::BaseController kế thừa từ ActionController::Base, mặc dù tôi đang đưa ra giải pháp cho trường hợp cụ thể của bạn

Ref bài đăng này: Implementing Rails APIs like a professional

1) Xác định điều khiển ứng dụng theo cách thông thường trong app/controllers/application_controller.rb như

class ApplicationController < ActionController::Base 
end 

2) Xác định cơ sở điều khiển api cụ thể là Api :: V1 :: BaseController trong app/controllers/api/v1/base_controller.rb mà sẽ thừa hưởng từ ApplicationController (trường hợp của bạn) như

class Api::V1::BaseController < ApplicationController 
end 

3) Xác định bộ điều khiển api của bạn như Api::V1::UsersController trong app/controllers/api/v1/users_controller.rb mà sẽ thừa hưởng từ Api :: V1 :: BaseController

class Api::V1::UsersController < Api::V1::BaseController 
end 

4) Thêm tất cả các bộ điều khiển tiếp theo như Api::V1::UsersController (bước 3)

Sau đó tuyến sẽ chứa namespace định tuyến trong config/routes.rb

namespace :api do 
    namespace :v1 do 
    resources :users do 
     #user routes goes here 
    end 
    # any new resource routing goes here 
    # resources :new_resource do 
    # end 
    end 
end 
+0

Mặc dù điều này đã không trực tiếp trả lời câu hỏi của tôi, nó đã cho tôi nhiều thiết kế rộng hơn cho lựa chọn API. Cảm ơn bạn. – GingerTech