These are chat archives for dry-rb/chat

25th
Jun 2018
Chris Richards
@cmrichards
Jun 25 2018 16:52

@Cervajz In this situation I'm always unsure if your custom machine_ids validation will run if the value for the field (machine_ids) is missing. I think it might not, which would make this line not needed:

if machine_ids.present?

I could be, and probably am, wrong about this. So please check first!

Jaromír Červenka
@Cervajz
Jun 25 2018 16:57
@cmrichards Hi. I did check it and it runs if you send an empty array:
‹master*!+2› »»»» rails c                                                                                                                           0|18:56:47
Loading development environment (Rails 5.2.0)
[1] pry(main)> reload!; SupportTickets::CreateSchema.with(machine_repository: Machine).call({machine_ids: []})
Reloading...

[12, 21] in /Volumes/Data/Users/cervajz/Projects/Personal/Ruby/virtio/api/app/schemas/support_tickets/create_schema.rb
   12:
   13:     optional(:machine_ids).maybe(:array?)
   14:
   15:     validate(exists?: :machine_ids) do |machine_ids|
   16:       byebug
=> 17:       machine_repository.where(id: machine_ids).count == machine_ids.count
   18:     end
   19:
   20:     validate(exists?: :user_id) do |user_id|
   21:       user_repository.find_by(id: user_id).present?
(byebug) c
   (0.8ms)  SELECT COUNT(*) FROM "machines" WHERE 1=0
=> #<Dry::Validation::Result output={:machine_ids=>[]} errors={:user_id=>["is missing"], :subject=>["is missing"], :message=>["is missing"], :priority=>["is missing"]}>
[2] pry(main)>
AR is OK with it, but I wanted to avoid that select to DB
Chris Richards
@cmrichards
Jun 25 2018 17:06
@Cervajz ah ok
@Cervajz If you don't pass in the machine_ids field then the custom validation won't run right?
Jaromír Červenka
@Cervajz
Jun 25 2018 17:11
@cmrichards It does run:
[~/P/P/R/v/api|2.5.1|2.7.10]
‹master*!+2› »»»» rails c                                                                                                                           0|19:10:53
Loading development environment (Rails 5.2.0)
[1] pry(main)> reload!; SupportTickets::CreateSchema.with(machine_repository: Machine).call({})
Reloading...

[12, 21] in /Volumes/Data/Users/cervajz/Projects/Personal/Ruby/virtio/api/app/schemas/support_tickets/create_schema.rb
   12:
   13:     optional(:machine_ids).maybe(:array?)
   14:
   15:     validate(exists?: :machine_ids) do |machine_ids|
   16:       byebug
=> 17:       machine_repository.where(id: machine_ids).count == machine_ids.count
   18:     end
   19:
   20:     validate(exists?: :user_id) do |user_id|
   21:       user_repository.find_by(id: user_id).present?
(byebug) machine_ids
nil
(byebug) c
   (0.9ms)  SELECT COUNT(*) FROM "machines" WHERE "machines"."id" IS NULL
NoMethodError: undefined method `count' for nil:NilClass
from /Volumes/Data/Users/cervajz/Projects/Personal/Ruby/virtio/api/app/schemas/support_tickets/create_schema.rb:17:in `block (2 levels) in <module:SupportTickets>'
[2] pry(main)>
I think it is caused by the optional validation
What I'd like is to have an option for default values if the optional variable is not provided. I have GQL on top of dry-validation & dry-transaction, which has got that and it's very handy:
# app/graphql/types/inputs/support_ticket_attributes.rb
module Types
  module Inputs
    class SupportTicketAttributes < BaseInputObject
      argument :subject, String, required: true
      argument :message, String, required: true
      argument :priority, Boolean, required: false, default_value: false
      argument :machineIds, [ID], required: false, default_value: []
    end
  end
end
So I have basically two places where I define schema for the input. It's maybe a duplication, but I wanted to have the "business layer" (transactions) independent from the API layer
Chris Richards
@cmrichards
Jun 25 2018 22:36
@Cervajz dry-validation is just for validation, so not sure if the concept of a default value makes sense here.
@Cervajz perhaps dry-struct could help you here?