2012-01-11 26 views
11

Tôi đã nhìn thấy mã này trong một hướng dẫn đường ray tôi đang làmray/ruby ​​"và trả lại false" cú pháp

def access_denied 
    redirect_to login_path, :notice => "Please log in to continue" and return false 
end 

Trước ray học, tôi đã làm một số lượng lớn các nghiên cứu ruby ​​và không ai trong số những cuốn sách Tôi đọc đề cập đến cú pháp "và trả về false" ở đây. Tôi không thể tìm thấy bất kỳ đề cập đến nó trong cú pháp đường ray, là bất cứ ai có thể cung cấp một liên kết hoặc bất kỳ lời giải thích rằng sẽ rõ ràng này lên?

Tôi không hiểu nhu cầu về "và" ở đây vì tôi nghĩ ruby ​​sẽ luôn trả về biểu thức được đánh giá cuối cùng.

+0

Ồ, tôi nghĩ bạn đang hỏi * tại sao * nó sẽ được sử dụng. Trong mọi trường hợp, nếu nó đang được sử dụng bởi một bộ lọc như được mô tả trong câu trả lời của tôi, rất cảnh giác. –

Trả lời

21

chỉ có để bạn có thể viết trả về false vào cùng dòng với tuyên bố trước đó.

Đó là tương đương để làm điều này:

redirect_to login_path, :notice => "Please log in to continue" 
return false 

nó không hoàn toàn giống nhau bởi vì với "và" nó sẽ chỉ trả lại false nếu redirect_to phương thức trả về một cái gì đó mà không phải là nil hoặc false nhưng vì nó hầu như luôn trả về một cái gì đó không phải là nil cũng không false thì bên phải của câu lệnh luôn được thực hiện (và false được trả lại).

Các trong Ruby chỉ là một bí danh để & & và hoạt động chính xác như nó chỉ có một sự khác biệt, nó có một ưu tiên thấp hơn so với tất cả các phần khác của báo cáo kết quả, vì vậy đầu tiên nó đánh giá bất cứ điều gì là trên nó trái và sau đó được áp dụng. Ruby cũng có số hoặc giống như || nhưng có mức ưu tiên thấp hơn trong biểu thức.

+1

Nếu bạn muốn thêm trả về luôn thực hiện nhưng bạn ** không tự tin rằng biểu thức đầu tiên sẽ luôn trả về không sai, bạn cũng có thể sử dụng dấu chấm phẩy thay vì 'và', như sau:' do_something đối số, đối số; return false' –

2

Loại cấu trúc này được sử dụng để sử dụng với bộ lọc, khi các giá trị trả về bộ lọc được mong đợi. false sẽ tạm dừng xử lý yêu cầu thông thường.

Vì vậy, nếu một bộ điều khiển trông như thế này:

class FooController < ActionController::Base 
    before_filter :access_denied 
    # etc. 
end 

Không ai trong số các hoạt động của bộ điều khiển sẽ chạy; Phương pháp này đã được nhiều khả năng được thiết kế để được gọi từ một bộ lọc, như:

def check_access 
    return access_denied unless current_user.has_access 
end 

Những giá trị này trở lại ngày lọc được bỏ qua.

Nó có thể được sử dụng như một phương pháp bình thường trong một hành động để ngừng xử lý các hành động và trở lại sau khi chuyển hướng, do đó, không có logic khác/rendering/etc. được chạy bên trong bộ điều khiển.

3

redirect_to login_path, :notice => "Please log in to continue" là biểu thức bình thường trong Ruby không trả về false (hoặc không, xem source code), do đó chương trình thực hiện tiếp tục (để kiểm tra phần thứ hai sau AND) và return false có thể được thực hiện.

1

Tài liệu về khai thác: Under the "Defined?, And, Or, and Not" section

Sử dụng and là hữu ích cho chaining được kết hoạt động có liên quan nhau cho đến khi một trong số họ trả nil hoặc false. Bạn có thể sử dụng nó như bạn đã cho thấy trong câu hỏi của bạn hoặc bạn cũng có thể sử dụng nó để ngắn mạch dòng mã.

# Short circuit example 
blog = Blog.find_by_id(id) and blog.publish! 

Blog chỉ được .publish! gọi là nếu find_by_id thành công.

Trong ví dụ của bạn:

def access_denied 
    redirect_to login_path, :notice => "Please log in to continue" and return false 
end 

Họ chỉ sử dụng nó để viết mã gọn hơn trên cùng một dòng.

Tuy nhiên, nó cũng rất hữu ích cho một hành động điều khiển, nơi bạn có thể được dựng hình dựa trên điều kiện và bạn không muốn nhận Rails "nhiều làm cho" cảnh báo:

def show 
    if something 
    render :partial => 'some_partial' 
    end 

    render :partial => 'some_other_partial' 
end 

Rails sẽ cung cấp cho bạn một cảnh báo nếu something trả về true vì bạn có nhiều câu lệnh hiển thị được đánh giá trong hành động. Tuy nhiên, nếu bạn thay đổi nó thành

if something 
    render :partial => 'some_partial' and return 
end 

nó sẽ cho phép bạn ngừng thực hiện hành động.

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