thebenman
thebenman

Reputation: 1621

Writing validations for an array of hashes parameter in rails

I have a new API attribute which is an array of hashes and I would like to validate it as part of built-in rails validation. Since this is a complex object I'm validating I am not finding any valid examples to refer from.

The parameter name is books which are an array of hashes and each hash has three properties genre which should be an enum of three possible values and authors which should be an array of integers and bookId which should be an integer.

Something like this books: [{bookId: 4, genre: "crime", authors: [2, 3, 4]}]

If it's something like an array I can see the documentation for it https://guides.rubyonrails.org/active_record_validations.html here but I am not finding any examples of the above scenarios.

I'm using rails 4.2.1 with ruby 2.3.7 it would be great if you could help me with somewhere to start with this.

For specifically, enum validation I did find a good answer here How do I validate members of an array field?. The trouble is when I need to use this in an array of hashes.

Upvotes: 2

Views: 1542

Answers (1)

spickermann
spickermann

Reputation: 106932

You can write a simple custom validation method yourself. Something like this might be a good start:

validate :format_of_books_array

def format_of_books_array
  unless books.is_a?(Array) && books.all? { |b| b.is_a?(Hash) }
    errors.add(:books, "is not an array of hashes") 
    return
  end

  errors.add(:books, "not all bookIds are integers")  unless books.all? { |b| b[:bookId].is_a?(Integer) }
  errors.add(:books, "includes invalid genres")       unless books.all? { |b| b[:genre].in?(%w[crime romance thriller fantasy]) }
  errors.add(:books, "includes invalid author array") unless books.all? { |b| b[:authors].is_a?(Array) && b[:authors].all? { |a| a.is_a?(Integer) } }
end

Upvotes: 4

Related Questions