Làm thế nào để kiểm tra nếu các tham số tồn tại trong đường ray


179

Tôi đang sử dụng câu lệnh IF trong Ruby on Rails để thử và kiểm tra nếu tham số yêu cầu được đặt. Bất kể cả hai tham số có được đặt hay không, phần đầu tiên của phần sau nếu khối được kích hoạt. Làm cách nào tôi có thể làm cho phần này CHỈ được kích hoạt nếu cả hai param [: one] và params [: hai] được đặt?

if (defined? params[:one]) && (defined? params[:two])
 ... do something ...
elsif (defined? params[:one])
 ... do something ...
end

10
@Nakilon: Cho rằng đó paramslà một phương thức điều khiển Rails (điều đó xảy ra để trả về HashWithIndifferentAccess), đó là về Rails.
mu quá ngắn

Câu trả lời:


348

Bạn muốn has_key?:

if(params.has_key?(:one) && params.has_key?(:two))

Chỉ cần kiểm tra if(params[:one])sẽ bị đánh lừa bởi một giá trị "có nhưng không" và "có nhưng sai" và bạn đang hỏi về sự tồn tại. Bạn có thể cần phân biệt:

  • Không có ở đó.
  • Có nhưng nil.
  • Có nhưng false.
  • Có nhưng một chuỗi trống.

cũng. Khó có thể nói mà không có thêm chi tiết về tình hình chính xác của bạn.


3
@sawa Không thể truyền niltham số. Nếu tham số tồn tại, nó sẽ là một chuỗi rỗng.
Jacob Relkin

5
@Jacob: Không có gì đảm bảo rằng paramschúng tôi chưa được xử lý trước khi chúng tôi đến nơi chúng tôi đang kiểm tra những gì trong đó. Do đó danh sách các trường hợp đặc biệt có thể của tôi để kiểm tra. Tốt nhất để nói chính xác những gì bạn có nghĩa là IMHO.
mu quá ngắn

1
@muistooshort xấu của tôi, đó là Python :(
FloatingRock

2
Trong Rails 5, đối tượng params không còn là hàm băm và tôi không thấy key?phương thức này. edgeapi.rubyonrails.org/groupes/ActionControll/ Kẻ
stephen.hanson

1
@muistooshort ơi, đẹp quá. Tôi vẫn còn một chút do dự khi sử dụng các phương pháp không phải là một phần của API được ghi lại, nhưng tôi chắc chắn rằng điều đó đủ an toàn. Tôi đã gọi params.to_h.key?cho bây giờ.
stephen.hanson

86

tôi là người hâm mộ của

params[:one].present?

Chỉ vì nó giữ params[sym]hình thức để dễ đọc hơn.


1
Tốt hơn, 3 ký tự ngắn hơn, đơn giản hơn.
Bengala

Điều này nên được phản hồi hợp lệ tốt nhất!
jacktrade

4
Cẩn thận sử dụng hiện tại? với booleans (phương thức không xác định 'hiện tại' cho true: TrueClass). Câu trả lời được chấp nhận với has_key? làm việc cho tất cả các loại.
StCleezy

2
Để rõ ràng điều này không hoạt động trong một số trường hợp như eg.present? => false Vì vậy, sẽ không hoạt động khi ví dụ truyền các tham số qua cơ thể json vì có thể truyền booleans.
James

1
nếu bạn đang sử dụng logic này trong một khung nhìn, thì hiện tại sẽ thất bại vì mảng tham số đã được gọi và thất bại nếu không. has_keythay vào đó cung cấp cho bạn những gì bạn đang tìm kiếm.
Jerome

22

dùng chỗ trống? http://api.rubyonrails.org/groupes/Object.html#method-i-blank-3F

unless params[:one].blank? && params[:two].blank?

sẽ trả về true nếu trống hoặc không

cũng ... điều đó sẽ không hoạt động nếu bạn đang kiểm tra các giá trị boolean .. kể từ khi

>> false.blank?
=> true

trong trường hợp đó bạn có thể sử dụng

unless params[:one].to_s.blank? && params[:two].to_s.blank?

3
Hoặc present?trả về ngược lại blank?. Vì vậy, bạn có thể biến nó unlessthành một ifnếu bạn muốn.
Inkling

@Inkling hoạt động được, nhưng nội tuyến unlessthì ok. Nhưng vâng, tôi thích hơn ifvớipresent?
Orlando

18

Bạn có thể viết nó ngắn gọn hơn như sau:

required = [:one, :two, :three]
if required.all? {|k| params.has_key? k}
  # here you know params has all the keys defined in required array
else
  ...
end

1
Tôi thích cách làm sạch này. Tôi mới biết đến Ruby. Bất kỳ cạm bẫy hoặc trường hợp cạnh bị bỏ lỡ tôi nên biết?
Sean

10

Đơn giản như chiếc bánh:

if !params[:one].nil? and !params[:two].nil?
  #do something...
elsif !params[:one].nil?
  #do something else...
elsif !params[:two].nil?
  #do something extraordinary...
end

3
Điều đó không kiểm tra xem tham số có ở đó không nhưng thực sự được đặt thành không.
Daemin

@Daemin Trong thực tế, một tham số không thể được đặt thành không trong tiêu đề yêu cầu. Đó là con số không hoặc một chuỗi.
Jacob Relkin

Có nhưng như những người khác đã tuyên bố, nó có thể bị sửa đổi bởi một thứ khác, plugin, đá quý hoặc mã của riêng bạn hoặc không thể phân tích cú pháp vì một lý do kỳ quái nào đó.
Daemin

4
Làm một chiếc bánh thực sự rất phức tạp
Cesar

tại sao bạn không sử dụng trừ khi
Alireza Rahmani Khalili

5
if params[:one] && params[:two]
 ... do something ...
elsif params[:one]
 ... do something ...
end

5

Một cách rất đơn giản để cung cấp các giá trị mặc định cho thông số của bạn: params[:foo] ||= 'default value'


2
bạn cũng có thể làm như params.fetch(:foo, 'default value')vậy
Mario Pérez

5

Tôi vừa đọc cái này trên các lớp RubyInRails http://api.rubyonrails.org/groupes/Object.html#method-i-blank-3F

bạn có thể dùng blank? phương thức tương đương vớiparams[:one].nil? || params[:one].empty?

(ví dụ)

if params[:one].blank? 
  # do something if not exist
else
  # do something if exist
end

Hoàn hảo, tôi đã sử dụngparams[:one].nil? || params[:one].empty?
GOXR3PLUS

Có khóa là phương thức phù hợp, phương thức của bạn cho rằng param này đã tồn tại nên bạn xác nhận nil trên nil có thể hoạt động nhưng không phải là phương pháp tốt nhất.
Paul Brunache

3

Bạn cũng có thể làm như sau:

unless params.values_at(:one, :two, :three, :four).includes?(nil)
 ... excute code ..
end 

Tôi có xu hướng sử dụng giải pháp trên khi tôi muốn kiểm tra nhiều hơn một hoặc hai params.

.values_at trả về và mảng với nil ở vị trí của bất kỳ khóa param không xác định nào. I E:

some_hash = {x:3, y:5}
some_hash.values_at(:x, :random, :y}

sẽ trả lại như sau:

[3,nil,5] 

.includes? (nil) sau đó kiểm tra mảng cho bất kỳ giá trị nil nào. Nó sẽ trả về true là mảng bao gồm nil.

Trong một số trường hợp, bạn cũng có thể muốn kiểm tra xem params không chứa và chuỗi rỗng trên giá trị sai.

Bạn có thể xử lý các giá trị đó bằng cách thêm mã sau vào bên trên câu lệnh trừ khi.

params.delete_if{|key,value| value.blank?}

tất cả cùng nhau trông như thế này:

 params.delete_if{|key,value| value.blank?}
 unless params.values_at(:one, :two, :three, :four).includes?(nil)
   ... excute code ..
  end

Điều quan trọng cần lưu ý là xóa_if sẽ sửa đổi hàm băm / param của bạn, vì vậy hãy thận trọng khi sử dụng.

Giải pháp trên rõ ràng cần thêm một chút công việc để thiết lập nhưng đáng giá nếu bạn đang kiểm tra nhiều hơn thì chỉ cần một hoặc hai thông số.


3

Ngoài các câu trả lời trước: has_key?has_value?các lựa chọn thay thế ngắn hơn ở dạng key?value?. Nhóm Ruby cũng đề xuất sử dụng các lựa chọn thay thế ngắn hơn, nhưng để dễ đọc một số vẫn có thể thích các phiên bản dài hơn của các phương pháp này.

Vì vậy, trong trường hợp của bạn, nó sẽ giống như

if params.key?(:one) && params.key?(:two)
  ... do something ...
elsif params.key?(:one)
  ... do something ...
end

Lưu ý! .key?sẽ chỉ kiểm tra nếu khóa tồn tại và bỏ qua bất kỳ giá trị nào có thể. Ví dụ:

2.3.3 :016 > a = {first: 1, second: nil, third: ''}
  => {:first=>1, :second=>nil, :third=>""}
2.3.3 :017 > puts "#{a.key?(:first)}, #{a.key?(:second)}, #{a.key?(:third), #{a.key?(:fourth)}}"
true, true, true, false

2

Đây là những gì tôi làm,

before_action :validate_presence

và sau đó các phương pháp sau:

    def check_presence
  params[:param1].present? && params[:param2].present?
 end

 def validate_presence
  if !check_presence
    render json:  {
                      error:  {
                                message: "Bad Request, parameters missing.",
                                status: 500
                              }
                    }
  end
 end

1

Chỉ cần ghép cái này cho cùng một vấn đề:

before_filter :validate_params

private

def validate_params
  return head :bad_request unless params_present?
end

def params_present?  
  Set.new(%w(one two three)) <= (Set.new(params.keys)) &&
  params.values.all?
end

dòng đầu tiên kiểm tra xem các khóa mục tiêu của chúng tôi có trong các khóa của params bằng cách sử dụng tập hợp con <= không? nhà điều hành. Vô số.all? không có khối trên mỗi mặc định trả về false nếu bất kỳ giá trị nào là 0 hoặc sai.


0
if params[:one] && param[:two]
  ... excute code ..
end

Bạn cũng có thể kiểm tra xem các tham số có trống không bằng cách sử dụng params [: hai] .empty


1
Trong khi điều này bao gồm cả trường hợp cả hai tham số được xác định. Nó không bao gồm trường hợp một trong số họ đánh giá là sai.
EmFi

0

Tôi cố gắng trả lời muộn, nhưng từ tầm nhìn xa:

Nếu bạn muốn biết liệu các giá trị trong hàm băm (bất kỳ) có được đặt hay không, tất cả các câu trả lời trên đều đúng, tùy theo quan điểm của chúng.

Nếu bạn muốn kiểm tra thông số (GET / POST ..) của mình, bạn nên sử dụng thứ gì đó đặc biệt hơn với giá trị mà bạn mong đợi là giá trị của params[:one], đại loại như

if params[:one]~=/   / and  params[:two]~=/[a-z]xy/

bỏ qua tham số (GET / POST) như thể chúng không được đặt, nếu chúng không phù hợp như mong đợi

chỉ cần if params[:one] có hoặc không phát hiện đúng / không là một bước để mở trang của bạn để hack, bởi vì, đây thường là bước tiếp theo để sử dụng một cái gì đó như select ... where params[:one] ..., nếu điều này được dự định hay không, hoạt động hoặc trong hoặc sau một khung.

một câu trả lời hoặc chỉ là một gợi ý

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.