2012-01-21 28 views
6

Tôi đã xem qua phương pháp sinatra và tôi đang bối rối về cách hoạt động của nó.Sinatra :: Base.condition thực sự làm gì?

Tôi có một đoạn mã:

def auth user 
    condition do 
    redirect '/login' unless user_logged_in? 
    end 
end 

nào kiểm tra xem nếu người dùng được đăng nhập cho các tuyến đường nhất định, một con đường dụ:

get '/', :auth => :user do 
    erb :index 
end 

Phương pháp user_logged_in? được định nghĩa trong một helper trong thư mục lib của dự án:

def user_logged_in? 
    if session[:user] 
    @user = session[:user] 
    return @user 
    end 
    return nil 
end 

Vì vậy, câu hỏi là: Khối condition biết nội dung của session[:user] chứa khi nào, tại tuyến đường get '/', session[:user] chưa được đặt?

Phương thức condition được xác định trong trang GitHub sau: sinatra base condition method Cảm ơn.

Trả lời

4

Khi bạn xác định tuyến đường, khóa của mỗi thành viên của băm tùy chọn là called as a method, with the value passed as the arguments.

Vì vậy, khi bạn thực hiện get '/', :auth => :user do ... phương thức auth được gọi với đối số :user. Điều này lần lượt gọi phương thức condition với khối.

Phương thức condition thực tế là defined just above where you link to là cách sử dụng của nó. Nó trông giống như thế này:

def condition(name = "#{caller.first[/`.*'/]} condition", &block) 
    @conditions << generate_method(name, &block) 
end 

Phương pháp generate_method chuyển khối vào một phương thức với tên được đặt, và sau đó phương pháp này sẽ được lưu trong mảng @conditions. Nội dung của @conditions sau đó được lưu với định nghĩa của tuyến đường và @conditions sẽ bị xóa cho định nghĩa tuyến đường tiếp theo.

Tại thời điểm này, khối mã được chuyển đến condition chưa được thực thi. Nó đã có hiệu lực được lưu lại cho sau này.

Khi có yêu cầu thực tế, nếu đường dẫn yêu cầu khớp với tuyến đường, sau đó each condition associated with that route is executed để kiểm tra xem nó có được đáp ứng hay không. Trong ví dụ này, đây là khi redirect '/login' unless user_logged_in? được thực hiện lần đầu tiên, do đó, session sẽ được thiết lập và session[:user] sẽ khả dụng (hoặc không nếu chúng chưa đăng nhập).

Điều quan trọng cần hiểu về điều này là khi bạn chuyển một khối cho một phương thức, mã trong khối đó không nhất thiết phải được gọi ngay lập tức.Trong trường hợp này, mã trong khối chỉ được gọi khi một yêu cầu thực tế đến.

+0

cảm ơn bạn rất nhiều vì đã giải thích cẩn thận. Kỹ năng đọc Ruby của tôi hoàn toàn bối rối khi tôi nhìn vào phương pháp 'điều kiện'. Mặc dù đọc qua các mã vẫn cảm thấy khá đau đớn bạn đã cho phép tôi hiểu _what_ đang xảy ra. Chúc mừng. –

2

Vì Sinatra chịu trách nhiệm gọi cả phương thức điều kiện và phương thức tuyến đường. Do đó, bạn nên an toàn khi giả định rằng bất kỳ điều gì được đặt khi phương thức tuyến đường của bạn thực hiện cũng được đặt khi điều kiện của bạn thực thi.

Hãy xem mã bắt đầu here: các điều kiện được gọi là từng cái một; nếu tất cả các điều kiện phù hợp, thì khối được gọi. Không có gì xảy ra nhiều giữa các điều kiện kiểm tra và gọi khối: chúng cơ bản chạy với cùng một ngữ cảnh.

+0

Cảm ơn vì điều này, @matt đã có thể hiển thị những gì đang xảy ra trong bối cảnh chương trình của tôi, đó là những gì tôi đã làm sau. –

Các vấn đề liên quan