Lors de la création et de la mise à jour d'une colonne de type booléen avec l'API Rails, je souhaite lire des types autres que booléen
$ rails -v
Rails 6.0.3.2
$ rails g model Post body:text opened:boolean
app/models/post.rb
class Post < ApplicationRecord
validates :opened, inclusion: { in: [true, false]}
end
Si vous faites cela, vous devriez pouvoir tout lire sauf le booléen ...
$ curl localhost:3000/posts -X POST -H "Content-Type: application/json" -d '{"body": "hoge", "opened": "moge"}'
{"status":"success","data":{"id":1,"body":"hoge","opened":true,"created_at":"2020-08-16T01:31:14.277Z","updated_at":"2020-08-16T01:31:14.277Z"}}
Spécifiez "moge" pour la colonne ouverte de booléen
Attente: comme il n'est pas booléen, il sera joué avec une erreur Condition réelle: cast à vrai et enregistré sans erreur
$ curl localhost:3000/posts -X POST -H "Content-Type: application/json" -d '{"body": "hoge", "opened": "0"}'
{"status":"SUCCESS","data":{"id":2,"body":"hoge","opened":false,"created_at":"2020-08-16T01:31:28.498Z","updated_at":"2020-08-16T01:31:28.498Z"}}
Attente: comme il n'est pas booléen, il sera joué avec une erreur Condition réelle: Cast en faux et enregistré sans erreur
Apparemment, il semble que la valeur sera transmise à l'état de distribution
Faire une validation personnalisée
app/validators/boolean_validator.rb
class BooleanValidator < ActiveModel::EachValidator
def validate_each(record, attr, _value)
before_value = record.send("#{attr}_before_type_cast")
record.errors.add(attr, "is invalid") unless %w[true false].include?(before_value.to_s.downcase)
end
end
app/models/post.rb
class Post < ApplicationRecord
validates :opened, boolean: true
end
$ curl localhost:3000/posts -X POST -H "Content-Type: application/json" -d '{"body": "hoge", "opened": "moge"}'
{"status":"error","data":{"opened":["is invalid"]}}
$ curl localhost:3000/posts -X POST -H "Content-Type: application/json" -d '{"body": "hoge", "opened": "0"}'
{"status":"error","data":{"opened":["is invalid"]}}
$ curl localhost:3000/posts -X POST -H "Content-Type: application/json" -d '{"body": "hoge", "opened": "true"}'
{"status":"success","data":{"id":3,"body":"hoge","opened":true,"created_at":"2020-08-16T02:25:18.211Z","updated_at":"2020-08-16T02:25:18.211Z"}}
$ curl localhost:3000/posts -X POST -H "Content-Type: application/json" -d '{"body": "hoge", "opened": "false"}'
{"status":"success","data":{"id":4,"body":"hoge","opened":false,"created_at":"2020-08-16T02:25:30.700Z","updated_at":"2020-08-16T02:25:30.700Z"}}
Comme prévu, tous sauf vrai et faux sont maintenant joués
Comment valider une colonne de type booléen dans Rails et la renvoyer comme une erreur si le type est différent Si vous l'implémentez avec l'URL ci-dessus, il sera pris dans rubocop de différentes manières, donc j'écris cet article