These are chat archives for dry-rb/chat

30th
Sep 2016
deepj
@deepj
Sep 30 2016 08:11
Hello, I use dry-validation for JSON schema validation. I’m not sure if it’s possible to define if some field is additionally, so it’s considered as an error.
Oskar Szrajer
@gotar
Sep 30 2016 08:35
yeap you can define some fields as optional
@deepj ^
deepj
@deepj
Sep 30 2016 08:43

I guess, an example is better.

json = <<~JSON
  {
    "id": 1,
    "this_field_is_invalid": "this field shouldn't be here!"
  }
JSON

InvoiceSchema = Dry::Validation.JSON do
  required(:id).filled(:int?)
end

puts InvoiceSchema.(JSON.parse(json)).messages

In this case I’d expect an error. I'd achieve if I have addionall this_field_is_invalidfiels in a json, so I get an error there is unknow field in the json. I hope this is clearer.

Oskar Szrajer
@gotar
Sep 30 2016 08:44
ah you want something like strong params. Remove all not definied keys and return an error
co it works as you want (there will be no erorr) but dry-v will only return valid (definied in schema data)
require "dry-validation"
require "json"

json = <<~JSON
  {
    "id": 1,
    "this_field_is_invalid": "this field shouldn't be here!"
  }
JSON

InvoiceSchema = Dry::Validation.JSON do
  required(:id).filled(:int?)
end

puts InvoiceSchema.(JSON.parse(json)).messages # => {}
puts InvoiceSchema.(JSON.parse(json)).output # => {id: 1}
deepj
@deepj
Sep 30 2016 08:48
This is for validating an external API. I want to sure if returning JSON doesn’t contain any additional fields which shouldn’t be there and it follows a schema strictly.
@gotar Ah, I see
thanks
Oskar Szrajer
@gotar
Sep 30 2016 08:52
it will not
it works like strong params will let only valid (definied in schema attrs)
if validation message is not important for you and you only want cast and let definied in schema data to go inside your app, you can use Dry::Struct
Oskar Szrajer
@gotar
Sep 30 2016 09:10
require "dry-struct"
require "json"

json = <<~JSON
  {
    "id": 1,
    "this_field_is_invalid": "this field shouldn't be here!"
  }
JSON

module Types
 include Dry::Types.module
end

class Invoice < Dry::Struct
  attribute "id", Types::Int
end

Invoice.(JSON.parse(json)).inspect # => #<Invoice id=1?
the same (almost) with struct
let only you define and change to object (easier to operate later in app)
deepj
@deepj
Sep 30 2016 09:11
@gotar Thanks Oskar, I’ll take look at that deeply
Vladimir Dralo
@vladra
Sep 30 2016 10:12
Hi all! Has anyone used dry-validation schema via DI with dry-system?
Vladimir Dralo
@vladra
Sep 30 2016 10:20
My use case: I'm testing service/operation which has validation schema. Schema needs access to DB to check uniq validation. But I'd like my unit test to run without touching DB. So I need to do something like Schema.with(repo: fake_repo)
Oskar Szrajer
@gotar
Sep 30 2016 10:33
you can stub anything, examples should be in repo
check berg repo too: https://github.com/icelab/berg
Vladimir Dralo
@vladra
Sep 30 2016 10:44

Tbh I don't see how it's possible. Berg is tested using feature tests, they don't have my case there. Example:

require 'schema' 

class Service
  include App::Import['repositories.users']

  def call(params)
    Schema.(params)
    # ....
  end
end

RSpec.describe Service do
  let(:service) { described.class.new(users: users_repo) }
  let(:users_repo) { instance_double(Repositories::Users, count: 5 }
end

So I'm able to do this with Service, replacing repo with double. But I'm not able to replace repository of Schema from test. I can update my Service class to have Schema.with(users_repo: users).(params). But I thought maybe I can use validation via DI in Service class somehow

Vladimir Dralo
@vladra
Sep 30 2016 10:59
and docs saying that using withrebuilds all the rules affecting performance, so I don't want this code to be in production to support tests :/
Tim Riley
@timriley
Sep 30 2016 12:15
One idea: Once we work out how to make those schemas cached/singletons via dry-system's auto-registration, you could choose to have them registered in the container and then inject the schemas like other deps
Piotr Solnica
@solnic
Sep 30 2016 12:36
@vladra just use with in tests and set repo to be a callable option ie option :repo, -> { ... } so that it does need to exist when you require the file with your schemas
Vladimir Dralo
@vladra
Sep 30 2016 12:52

@solnic Not sure I understand what do you mean. Here is better example of what I'm trying to achieve

module Validations
  UserForm = Core::Validation.Form do
    configure do |config|
      option :users_repo, App::Container['repositories.users']
    end
    # ... validations
  end
end

require 'validations/user_form'
class CreateUser
  include App::Import[users_repo: 'repositories.users']

  def call(params)
    Validation::UserForm.(params)
    # ...
  end
end

RSpec.describe CreateUser do
  let(:service) { described_class.new(users_repo: users_repo) }
  let(:users_repo) { instance_double(Repositories::Users, count: 5 }

  let(:params) { ... }
  it 'foo bars' do
    result = service.(params)
    expect(result).to ....
  end
end

So I need somehow to double users repository in Validation::UserForm which is used in CreateUser#call method. And I don't see how can I do it without DI. I was thinking about wrapping schema in some method to be able to use it as DI for my service/operation -> Validation::UserForm.run.(params). Can't find other proper way to accomplish this.

updated above
Vladimir Dralo
@vladra
Sep 30 2016 12:58
@timriley thats what I need, but based from your response it seems there are no way to do it now
@vladra ^
Piotr Solnica
@solnic
Sep 30 2016 13:27
you could also define a schema class and include Singleton which is now supported by dry-system, so in runtime it would be created just once, and inject schemas with DI
Vladimir Dralo
@vladra
Sep 30 2016 14:01
thanks for help, I will try it
Vladimir Dralo
@vladra
Sep 30 2016 14:19
@solnic and can I use schemas via inheritance?
Piotr Solnica
@solnic
Sep 30 2016 14:31
@vladra http://dry-rb.org/gems/dry-validation/basics/working-with-schemas/ see “Defining Base Schema Class”
Vladimir Dralo
@vladra
Sep 30 2016 15:05
@solnic Ah, I see now - you propose to define dependecies/options in base schema class. But that will mean that my base class will include all repositories that needs to do uniq validations, right?
Piotr Solnica
@solnic
Sep 30 2016 16:16
I don’t propose anything :) just showing how to use inheritance
Piotr Solnica
@solnic
Sep 30 2016 16:47
both dry-validation and types passed 50k downloads on rubygems, that’s a lot given the age of these gems :)
Luca Guidi
@jodosha
Sep 30 2016 16:47
:tada:
Oskar Szrajer
@gotar
Sep 30 2016 16:47
:clap:
Sergey Kukunin
@Kukunin
Sep 30 2016 17:29
@solnic don't you want to link to dry-rb on virtus readme page? considering there is no active development of virtus, and it's way more easier to find virtus comparing to dry-rb - it makes sense to point people to something better
Piotr Solnica
@solnic
Sep 30 2016 18:55
@Kukunin yes I wanted to do that
there’s a new maintainer but there was no activity since April