Suganya Selvarajan
Suganya Selvarajan

Reputation: 1082

check false.present? in Ruby On Rails

I have an API. I want to check all the blank values in the request body and reject them. Also I have few attributes which can have either true / false (boolean) as value.

sample request body

{
  "data": {
      "id": 123,
       "type": "abc",
       "attributes": {
          "is_abc": false,
           "name": "gtd",
           "is_dgc": true
         }
  }
}    

I am validating if the request body has any blank values and raise exception if any.

  def validate_blank_values(params)
    blank_keys = params.map { |key, value| key if value.blank? }.compact
    raise exception
  end

value.blank? rejects even the boolean attributes when the request has false as its value which is a valid value here. Tried

value.present?

Also behaves the same way. The problem with .nil? is it returns false for empty string also.

''.nil? => false

The problem with .empty? is

false.empty? => (undefined method `empty?' for false:FalseClass)

I want to reject the values when they are

  1. blank
  2. empty string
  3. nil

do not reject when

  1. proper value

  2. false as value

Suggest me a solution for this

Upvotes: 1

Views: 4151

Answers (2)

Chandan
Chandan

Reputation: 11797

There more then one way:

Solution 1

Converting to string, striping spaces and then testing if empty would do the job

enter image description here

value = false

As stated by @engineersmnky With rails you can use blank?:

value.to_s.blank?

With 2 conditions

value.class == String && value.blank?

With only ruby:

value.to_s.strip.empty?

With Regex

/^\s*$/.match?(value.to_s)

With 2 conditions

value.class == String && value.strip.empty?

To recursively test json

Option 1 With map and reduce

def is_empty(tmp)
  tmp.map {
    |k, v| v.class == Hash ? is_empty(v) : v.to_s.strip.empty?
  }.reduce { |r1, r2| r1 || r2 }
end

json = {
  "data": {
    "id": 123,
    "type": "abc",
    "attributes": {
      "is_abc": false,
      "name": "gtd",
      "is_dgc": true
    }
  }
}

puts is_empty(json)

Option 2 With reduce

def is_empty(tmp)
  tmp.reduce(false) {
    |result, (k, v)| v.class == Hash ? is_empty(v) : result || v.to_s.strip.empty?
  }
end

json = {
  "data": {
    "id": 123,
    "type": "abc",
    "attributes": {
      "is_abc": false,
      "name": "gtd",
      "is_dgc": true
    }
  }
}

puts is_empty(json)

Upvotes: 3

Vishal
Vishal

Reputation: 7361

You need to use multiple conditions here otherwise it won't work.

Try below condition

value.present? || value.class == FalseClass || value.class == TrueClass

P.S. - blank_keys = params.map { |key, value| key if value.blank? }.compact is not checking for nested values of attributes

Upvotes: 3

Related Questions