Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
Andy Holland
@AMHOL
Not sure what you mean, surely you send your data to the server at some point?
Christian Meier
@mkristian
yes, we do but client side validation is much more responsive. the AST idea I will look into it. as we already decided to have only 'simple' validation on the client and all those custom and more complex stuff stays on the server
Andy Holland
@AMHOL
Yeah, it would be nice in an ideal world, I just think the cost outweighs the benefits personally
Christian Meier
@mkristian
I personally are more on your side but it is not my decision I just need to find a solution :)
Fran Worley
@fran-worley
If you really don't want to write the js validations yourself you could just Ajax the data on change to the server and display any errors
Christian Meier
@mkristian
@fran-worley I want to have both and want to share the validation rules at some of them between the client and the server
Andy Holland
@AMHOL
Well if a client/my boss asked me to do that, my suggested solution would be let's leave that rabbit hole alone, have the user hit submit and display the errors in one hit, but I know that's not always an option :p
Christian Meier
@mkristian
well, I was hopping (not too much) that there is already some solution out there with dry-validation
but from hear I get the courage and question the client side validation approach tomorrow - let's see what response I get
Andy Holland
@AMHOL
Cool, well if you end up having to implement it and need help, feel free to post on https://discuss.dry-rb.org/, it will require some intimate knowledge of the library and would be an interesting project, so would be nice to have it documented
Christian Meier
@mkristian
sure will do
Andy Holland
@AMHOL
FYI you can return the ast like this:
require 'bundler/inline'
gemfile(true) { gem 'dry-validation' }

s = Dry::Validation.Schema(build: false) do
  required(:age) { int? & gt?(18) }
end

s.ast
# => [[:rule, [:age, [:and, [[:rule, [:age, [:predicate, [:key?, [[:name, :age], [:input, Undefined]]]]]], [:rule, [:age, [:and, [[:rule, [:age, [:key, [:age, [:predicate, [:int?, [[:input, Undefined]]]]]]]], [:rule, [:age, [:key, [:age, [:predicate, [:gt?, [[:num, 18], [:input, Undefined]]]]]]]]]]]]]]]]]
Christian Meier
@mkristian
cool
George Millo
@georgemillo
how do people test their dry-v schemas, if at all?
I started writing some custom RSpec matchers, then I realised that my spec files were practically identical to my schemas themselves:
# schema:
required(:name).filled
optional(:age).maybe

# spec:
expect(schema).to have_required_key(:name).filled
expect(schema).to have_optional_key(:age).maybe
which is better than no tests at all, but tests take time to write, and now I'm writing 2x as much code for very little extra benefit
what are people's thoughts on writing tests for their schemas? do you find it worth the effort?
George Millo
@georgemillo
(I'm thinking that if I'm going to create custom matchers, my time is probably better spent creating them for Reform validations, which of course use dry-v anyway, but the matchers themselves will have to be different)
Christopher Dennl-Ortega Arrieta
@cdennl
@georgemillo don't test the schema but the instance which uses the schema
George Millo
@georgemillo
@cdennl I thought as much. In my case that would be Reform
Christopher Dennl-Ortega Arrieta
@cdennl
the schema alone is pretty meaningless
@georgemillo yes
or the model / op which uses the schema
George Millo
@georgemillo
there's a gaping hole in the Reform ecosystem for some smart RSpec matchers that test the validations
Fran Worley
@fran-worley
@georgemillo I've started moving away from tests like that. I test the actual result. I.e if I pass in this input, I expect to get the following errors. I think you get a more reliable result that focuses more on what matters (when my object is valid vs invalid and why) than the exact code I used to get there. Less coupling on the exact implementation therefore less brittle tests etc.
Fran Worley
@fran-worley
Plus as soon as you get advanced edge cases that depend on injected objects (say current user) you either end up testing manually or having such a complex matcher that it slightly defeats the point of having such a clean implementation library like dry-validations ! (Just my personal opinion of course 😜)
Lucas Hosseini
@beauby
^— :+1:
George Millo
@georgemillo
@fran-worley yeah, my custom matchers work like you described (passing in input, seeing if its valid), rather than testing the actual code (not even sure how you'd do that, presumably there's some way to reflect on the Schema class to figure it out)
where I realise I've gone wrong through is testing things at such a low level, i.e. at the level of the schema itself rather than the place that uses it (e.g. a reform form)
Fran Worley
@fran-worley
@georgemillo Sounds really cool, might do a minitest equivalent and actually use it in Reform :)
George Millo
@georgemillo
I opened at issue over at Reform if anyone wants to weigh in on this further: trailblazer/reform#414
Hannes Nevalainen
@kwando
hmm, is there a way to check that error messages have been defined for all predicates? would be nice to just tell "something" to check if I have provided error messages for all custom predicates (don't like to blow up on Dry::Validation::MissingMessageError)
This doc has a link to a gem called dry-component but the link is dead
has this gem been renamed?
oh wait, Google suggests that this is the old name for dry-system
amirite?
Nikita Shilnikov
@flash-gordon
yep
Andrew Thauer
@andrewthauer

Question - I’m looking at using dry-rb to build a re-usable gem that allows the consuming application to define & configure the persistenance layer, and other infrastructure related dependencies. I’ve got this more or less working when I explictly ask the container to resolve the dependency just before I need the service.

class SaveMyEntity
  def call(entity)
    my_repo = MyContainer[‘persistence.my_repo’]
    my_repo.save(entity)
  end
end

I’m wondering if I can also use either dry-auto_inject and/or dry-system to also do this? However, from what I can see, using the auto loading and the auto injector work differently.

Import = Dry::AutoInject(MyContainer)
class SaveMyEntity
  include Import[‘persistence.my_repo’] # throws Dry::System::ComponentLoadError: could not load component
end
Tim Riley
@timriley
@andrewthauer That should work. How are you setting up that “my_repo” registration?
Andrew Thauer
@andrewthauer
Sorry, I realized that using Application.inject vs Dry::AutoInject seem to behave differently. My mistake, the above example does work, but the Application.injector (suggested by the dry-system example), throws the above exception.
Does one lazy load dependencies and the other does not?
Tim Riley
@timriley
Dry::System.injector will give you an injector that lazy loads for containers that aren’t finalized, yes
But it’ll only lazy load according to certain strategies (though we’re actively improving that), so if your “persistence.my_repo” registration falls outside of that, it’ll not work
Andrew Thauer
@andrewthauer
Import = Dry::AutoInject(Container) # works
Import = Container.injector #  throws Dry::System::ComponentLoadError: could not load component

I’m currently calling one of those 2 lines inside a module pretty much when the gem is initially loaded. The first line seems to work, but the 2nd throws the error when I use the Import in a subsequent ruby file. Should I be deferrring these until after the consuming application has a chance to register it’s own dependencies?

Basically, just trying to figure out the correct pattern to use moving forward. I’m not sure, if I should be bothering with dry-system in my case or just leverage dry-container and possibly dry-auto_inject.

Tim Riley
@timriley
You’re probably seeing an error with dry-system’s injector because it’s trying to do the lazy load as soon as it is included into a class
whereas plain auto-inject doesn’t do any lazy loading at all
which is why it doesn’t bother to resolve the deps until you actually initialize that class
in dry-system master branch we’ve actually changed lazy loading so it does it upon class initialization too, not at include-time anymore
so that might be worth trying