2014-04-09 50 views
49

Tôi có một trang hiển thị cho Người dùng của tôi và mỗi thuộc tính chỉ nên hiển thị trên trang đó, nếu nó không phải là số không và không phải là một chuỗi rỗng. Dưới đây tôi có bộ điều khiển của tôi và nó là khá khó chịu phải viết cùng một dòng mã @user.city != nil && @user.city != "" cho mỗi biến. Tôi không quá quen thuộc với việc tạo ra các phương pháp của riêng tôi, nhưng tôi có thể tạo ra một lối tắt để làm một cái gì đó như thế này: @city = check_attr(@user.city)? Hoặc có cách nào tốt hơn để rút ngắn quy trình này?Kiểm tra nếu không phải là không và không trống trong lối tắt Rails?

users_controller.rb

def show 
    @city = @user.city != nil && @user.city != "" 
    @state = @user.state != nil && @user.state != "" 
    @bio = @user.bio != nil && @user.bio != "" 
    @contact = @user.contact != nil && @user.contact != "" 
    @twitter = @user.twitter != nil && @user.twitter != "" 
    @mail = @user.mail != nil && @user.mail != "" 
end 

Trả lời

139

Có một phương pháp mà thực hiện điều này cho bạn:

def show 
    @city = @user.city.present? 
end 

Các present? thử nghiệm phương pháp không- nil cộng có nội dung. Các chuỗi rỗng, các chuỗi chứa dấu cách hoặc tab, được coi là không có.

Kể từ khi mô hình này là quá phổ biến thậm chí còn có một phím tắt trong ActiveRecord:

def show 
    @city = @user.city? 
end 

Đây là tương đương.

Lưu ý, thử nghiệm so với nil hầu như luôn dư thừa. Chỉ có hai giá trị sai về mặt logic trong Ruby: nilfalse. Trừ khi nó có thể cho một biến là đen false, đây sẽ là đủ:

if (variable) 
    # ... 
end 

Đây là một lợi thế để thông thường if (!variable.nil?) hoặc if (variable != nil) thứ mà thỉnh thoảng xuất hiện. Ruby có khuynh hướng bảo vệ một loại biểu hiện giảm thiểu hơn.

Một lý do bạn muốn so sánh với nil là nếu bạn có biến số ba trạng thái có thể là true, false hoặc nil và bạn cần phải phân biệt giữa hai trạng thái cuối cùng.

+6

Lưu ý, như của Ruby 2.3.0 bạn có thể loại bỏ nhiều kiểm tra không cần thiết bằng cách sử dụng toán tử cô đơn, một cái gì đó như 'if @user && @ user.authenticated' có thể đơn giản trở thành' if @ user & .authenticated' –

8

Bạn có thể sử dụng .present? mà đi kèm bao gồm trong ActiveSupport.

@city = @user.city.present? 
# etc ... 

Bạn thậm chí có thể viết nó như thế này

def show 
    %w(city state bio contact twitter mail).each do |attr| 
    instance_variable_set "@#{attr}", @user[attr].present? 
    end 
end 

Nó đáng chú ý rằng nếu bạn muốn kiểm tra nếu có điều gì là trống, bạn có thể sử dụng .blank? (đây là điều ngược lại của .present?)

Ngoài ra, không sử dụng foo == nil. Sử dụng foo.nil? để thay thế.

+0

bạn có thể giải thích cách dòng đầu tiên hoạt động không ..? –

+0

@Mayank, OP sẽ đặt một biến mẫu thành giá trị 'true' /' false'. 'reciever.present?' sẽ trả về true nếu 'receiver' là một giá trị không trống. Vui lòng xem tài liệu tôi đã liên kết để được giải thích thêm. – naomik

+0

cảm ơn tôi đã nhận được điểm của bạn nhưng tôi không thể hiểu cách instance_variable_set "@ # {attr}", @user [attr] .present? sẽ làm việc..? –

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