Where communities thrive


  • Join over 1.5M+ people
  • Join over 100K+ communities
  • Free without limits
  • Create your own community
People
Activity
  • Feb 20 17:31
    jswanner commented #141
  • Feb 20 06:15
    lazebny starred dry-rb/dry-types
  • Feb 19 22:35
    solnic commented #141
  • Feb 19 22:32

    solnic on v0.17.0

    (compare)

  • Feb 19 22:32

    solnic on master

    Bump dry-system to 0.17.0 (compare)

  • Feb 19 22:31

    solnic on 141-fix-compat-with-dry-configurable

    Bump dry-system to 0.17.0 (compare)

  • Feb 19 22:31

    dry-bot on master

    [devtools] update changelog.yml… [devtools] sync (compare)

  • Feb 19 22:27

    solnic on 141-fix-compat-with-dry-configurable

    (compare)

  • Feb 19 22:27

    solnic on master

    Fix compatibility with dry-conf… Merge pull request #142 from dr… (compare)

  • Feb 19 22:27
    solnic closed #142
  • Feb 19 22:27
    solnic closed #141
  • Feb 19 22:24
    solnic milestoned #141
  • Feb 19 22:23
    solnic opened #142
  • Feb 19 22:23

    solnic on 141-fix-compat-with-dry-configurable

    Fix compatibility with dry-conf… (compare)

  • Feb 19 21:12
    flash-gordon commented #141
  • Feb 19 20:45
    jswanner opened #141
  • Feb 19 20:45
    jswanner labeled #141
  • Feb 19 17:38
    pmackay starred dry-rb/dry-monads
  • Feb 19 17:18
    tomraithel starred dry-rb/dry-types
  • Feb 19 11:51
    yingce starred dry-rb/dry-types
Piotr Solnica
@solnic
we can (and will) have batteries-included gems that work with rom-rb etc. but they will be 1) simpler 2) extendible w/o monkey-patches
Fran Worley
@fran-worley
@solnic I still thank myself that I never went down the devise route. Unfortunately I did get sucked into CanCan for authorisation which is proving to be very difficult to unwind...
Piotr Solnica
@solnic
so ie I'm not interested in building things like devise, it's too big, too complex, from my experience devise was one of the biggest reasons why upgrading a rails app to new rails was close-to-impossible (as in, it'd be very risky and time consuming)
I've never seen an auth system with built-in ACL that was done right, not sure if it's even feasible to do haha
Fran Worley
@fran-worley
@solnic I reached the same conclusion. Dependencies like carrierwave and cancan have caused me so many headaches.
Piotr Solnica
@solnic
@greghuc hey Greg, you can define custom types with custom coercion logic, see here for an example
they can carry not only coercion logic but also constraints that will be used for validation (if you want to)
@fran-worley there are two reasons for that, first of all massive inheritence-based APIs, rather than having re-usable objects gems provided mixins or abstract classes (or both), secondly gems doing too much :)
@greghuc default behavior is to sanitize input based on key definitions and value type definitions, but sneaking in normalization is totally fine, I think it's gonna work well for you. We're currently working on 0.8.0 releases of types and validation so if you see something odd, just report an issue. We want to get to 1.0.0 asap so feedback is very welcome :)
Gregory Huczynski
@greghuc

Hi @solnic, thanks for feedback. So am I looking at:

  • JSON API input: dry-validation used to consume " hello@example.com " and return StrippedString("hello@example.com")
  • In domain world, have "Message" object (email + message attributes): dry-types used to represent email with Email type (i.g. string that matches regex). An Email type can be constructed from normal String or StrippedString

I am unclear at which point the supplied 'email' API input value gets converted into an Email type: at the end of input validation, or only when passed into domain "Message" object

Piotr Solnica
@solnic
@greghuc oh so you want to coerce a string into a custom type too?
personally I'd advocate against doing so, because you'd be using a validation schema also as a data-to-object-mapper, this is too much. I'd recommend focusing on pure data validation and then using something like a dry-type Struct to build a domain object from safe-and-clean data
structs from dry-types can build objects from hashes so you've got everything you need
Gregory Huczynski
@greghuc

@solnic I'm feeling my way forward on a web-app refactor.

I'm wondering about using some custom types in my domain objects. The only custom types that make sense are for Email and Url, and that's really regex enforcement, and ensuring lowercase (Email("hi@example.com == "HI@eXample.com"). Everything else is likely fine in normal ruby types.

But I'm still trying to work out the JSON API input end: that's what requires some extra normalisation. If I'm loading Email or Url types from the DB, I wouldn't need the normalisation, but I would still want to do regex enforcement and lowercasing, which would be encapsulated in the the custom types

Regarding "you'd be using a validation schema also as a data-to-object-mapper, this is too much". It's a hard one to call: I presume dry-validation can coerce a String into a DateTime? That looks a lot like data-to-object mapping ;-)
Gregory Huczynski
@greghuc
@solnic I think my underlying issue is how dry-validation and dry-types fit into a web-app (JSON DB-backed API in my case). I kind of want there to be two separate parts:
  • Input validation + coercion: takes user input, normalises it and coerces into simple base types (String, DateTime, and custom types like Url and Email), and returns a hash of these typed attributes. Or errors. dry-validation might do this.
  • Immutable, typed domain objects: a domain object is defined as a set of typed attributes. The object is either constructed from validated-input-hash, or from hash-loaded-from-database. Though hash-loaded-from-database may have had some type coercion (i.e. email stored as string in DB becomes Email type), or that type coercion is built into the domain object. dry-types might work for this
Got to go - back later!
Piotr Solnica
@solnic
:laughing:
@greghuc yeah but we're still dealing with ruby primitives
require 'dry-validation'

class Email
  attr_reader :value

  def self.new(input)
    super("#{input}.com")
  end

  def initialize(value)
    @value = value
  end
end

Dry::Types.register_class(Email)

schema = Dry::Validation.Form do
  key(:email).required(type?: Email)
end

puts schema.('email' => 'jane@doe').inspect
@greghuc ^^
output:
#<Dry::Validation::Result output={:email=>#<Email:0x007fe6f2353370 @value="jane@doe.com">} messages={}>
Fran Worley
@fran-worley
@solnic is my assumption here correct?
When a predicate is curried, we can get some, all or none of the argument values. The same happens when it is called so we can't make any assumptions about what args we receive and when.
Piotr Solnica
@solnic
@fran-worley yeah, you don't know if you've got all args, there's no mechanism for that (at least not yet)
Fran Worley
@fran-worley
@solnic think I might have to add that as otherwise I'll be overriding an intentional nil.
Piotr Solnica
@solnic
@fran-worley I believe this will turn out to be useful in many places, so feel free to add it
it's a matter of storing arity
ah, failing specs first in dry-rb/dry-logic#13 nice :)
it's easier to TDD when mostly you care about inputs/outputs right? :)
Fran Worley
@fran-worley
@solnic thats my plan. What do you think about the AST change?
Piotr Solnica
@solnic
I like it, this is a pretty useful piece of info
we're gonna allocate more arrays but that shouldn't hurt esp that we can simplify code in dry-v thanks to this change
Fran Worley
@fran-worley
I don't think we can loose the input value from the result ast just yet as it isn't always exactly the same. but for error messages in dry-v it means that you can just focus on the predicate part as that has all the info including the input
Piotr Solnica
@solnic
right, the result part of dry-logic is the complicated part
I hope we can improve this over time
I esp don't like that we evaluate input two times :(
Fran Worley
@fran-worley
and when you recreate the predicate it causes all sorts of issues as I keep loosing the argument names...
Piotr Solnica
@solnic
wow wait, wdym by 'recreate predicate'?
Fran Worley
@fran-worley
When you call predicate.curry it intern calls Predicate.new passing in the curried version as the block
Therefore it's not enough to get the argument names on initialisation as calling block.parameters after it has been curried simply returns :rest not the actual parameters
Piotr Solnica
@solnic
ah shit
yeah that's what I'm talking about when I say that it'd be great to see MRI getting better FP features rather than some rails-inspired nonsenses
Gregory Huczynski
@greghuc
@solnic thanks for the code. Will start on API refactor with dry-validation and dry-type soon.
Piotr Solnica
@solnic
well, we have no other choice than to extend predicate with options and store needed data there
Fran Worley
@fran-worley
@solnic thats what I figured is it a significant performance hit?
Piotr Solnica
@solnic
shouldn't be, we're gonna have more stuff stored in predicates but we don't create predicate instances at runtime in dry-v so
won't affect it too much