Nếu chuỗi trống thì trả về một số giá trị mặc định


93

Thường thì tôi cần kiểm tra xem một số giá trị có trống không và viết rằng "Không có dữ liệu" như vậy:

@user.address.blank? ? "We don't know user's address" : @user.address

Và khi chúng ta có khoảng 20-30 trường mà chúng ta cần xử lý theo cách này, nó sẽ trở nên xấu xí.

Những gì tôi đã làm là mở rộng lớp String với orphương thức

class String
  def or(what)
    self.strip.blank? ? what : self
  end
end

@user.address.or("We don't know user's address")

Bây giờ nó trông đẹp hơn. Nhưng nó vẫn còn thô và thô

Làm thế nào nó sẽ tốt hơn để giải quyết vấn đề của tôi. Có lẽ sẽ tốt hơn nếu bạn mở rộng ActiveSupport classhoặc sử dụng phương pháp trợ giúp hoặc mixin hoặc bất kỳ thứ gì khác. Những gì lý tưởng về ruby, kinh nghiệm của bạn và các phương pháp hay nhất có thể cho tôi biết.

Câu trả lời:


227

ActiveSupport thêm một presencephương thức vào tất cả các đối tượng trả về bộ thu của nó nếu present?(ngược lại với blank?), và nilnếu không.

Thí dụ:

host = config[:host].presence || 'localhost'

2
điều này thật tuyệt. Các vị trí đường ray mặc định được ưu tiên. Thanx!
fl00r

Đầu tiên nó được ưu tiên vì trong giải pháp của tôi, ít nhất tôi nên mở rộng String, Fixnum và NilClass. Và ở đây tôi chỉ có thể sử dụng mã rõ ràng mà không bycles
fl00r

12

Phrogz đã cho tôi ý tưởng trong nhận xét của PofMagicfingers, nhưng còn ghi đè thì sao | thay thế?

class String
  def |(what)
    self.strip.blank? ? what : self
  end
end

@user.address | "We don't know user's address"

2

Vì bạn đang làm điều này trong Ruby on Rails, có vẻ như bạn đang làm việc với một mô hình. Nếu bạn muốn một giá trị mặc định hợp lý ở mọi nơi trong ứng dụng của mình, bạn có thể (ví dụ) ghi đè addressphương thức cho Usermô hình của mình .

Tôi không biết ActiveRecord đủ tốt để cung cấp mã tốt cho việc này; trong Phần tiếp theo, nó sẽ giống như sau:

class User < Sequel::Model
  def address        
    if (val=self[:address]).empty?
      "We don't know user's address"
    else
      val
    end
  end
end

... nhưng đối với ví dụ ở trên, điều này có vẻ như bạn đang trộn logic chế độ xem vào mô hình của mình, đó không phải là một ý tưởng hay.


Vâng, đó là ý tưởng tồi để mặc định thiết lập trong các mô hình :) hình thức của tôi sẽ khóc
fl00r

2

Phương pháp hoặc của bạn có thể có một số tác dụng phụ không mong muốn, vì giá trị thay thế (mặc định) luôn được đánh giá, ngay cả khi chuỗi không trống.

Ví dụ

@user.address.or User.make_a_long_and_painful_SQL_query_here

sẽ làm thêm công việc ngay cả khi địa chỉ không trống. Có lẽ bạn có thể cập nhật điều đó một chút (xin lỗi về việc nhầm lẫn một chữ lót, cố gắng giữ cho nó ngắn gọn):

class String
  def or what = ""
    self.strip.empty? ? block_given? ? yield : what : self
  end
end

@user.address.or "We don't know user's address"
@user.address.or { User.make_a_long_and_painful_SQL_query_here }

nhận xét tốt. Hiểu rồi. Nhưng tại sao tất cả mã sẽ được thực thi? nhìn:a=2 ; a == 2 ? "ok" : @b = 3 ; @b; #=> nil
fl00r

2
Nó sẽ được thực hiện khi thực hiện cuộc gọi ban đầu, không phải với toán tử bậc ba. Tất cả các đối số sẽ được đánh giá khi gọi phương thức.
Tonttu

2

Có lẽ tốt hơn là mở rộng ActiveRecord hoặc các mô hình riêng lẻ thay vì Chuỗi.

Theo quan điểm của bạn, bạn có thể thích một mẫu rõ ràng hơn như

@user.attr_or_default :address, "We don't know the user's address"

Đây có phải là một phần của Active Record không? Không tìm thấy bất kỳ tài liệu tham khảo nào.
cabe56 27/12/13

0

Ruby:

unless my_str.empty? then my_str else 'default' end

RoR:

unless my_str.blank? then my_str else 'default' end
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.