These are chat archives for dry-rb/chat

17th
Aug 2016
:ghost:
Andy Nicholson
@anicholson
Aug 17 2016 04:01
I'm having trouble understanding how to implement a particular rule/predicate in dry-v
specifically, how to assert that a users' email is unique when scoped by their organisation_id
I can't put arbitrary Ruby in a rule block (AFAICT), and I don't know how to access the secondary field if I made this a predicate
oh, just saw Tim's message about the forum. I'll go there
Nick Sutterer
@apotonick
Aug 17 2016 07:42
@timriley @solnic the cell is completely based on DI, though. every dependency has to come in via the constructor, there's even a section in the getting started guide that will take 5 mins of your time to read :P
Tim Riley
@timriley
Aug 17 2016 09:31
What I mean, @apotonick, is that I'd want them to be "functional objects", that is, objects you can instantiate just once and then call over and over again with different "user data"
This means that the things passed to the constructor can't change
Which is why I mentioned earlier that the local data (I.e. What is specific to a single rendering) would be nice to pass in via the call method.
Local data == user-supplied data, like the things you'd get off the URL segments and URL Params, a "current user" object etc.
Nick Sutterer
@apotonick
Aug 17 2016 09:38
@timriley that's exactly how cells work
you can't call them again, you have to re-instate
which is why i suggested Cell.()
you can really only invoke it and then it's gone - i hate state as much as you do ;)
Tim Riley
@timriley
Aug 17 2016 09:42
Right. I'm suggesting that what is important to me is a separation of state that never changes (collaborating objects like repositories, etc.) which is provided via DI, and then the view "input", which is passed to #call. In this arrangement, you don't need to throw away your objects, and it works nicely with tools like dry-auto_inject.
In this arrangement, you don't need to throw away your objects.
Tim Riley
@timriley
Aug 17 2016 09:51
view = UsersIndex.new(repo: users_repo)
view.call(page: 1)
view.call(page: 2)
Nick Sutterer
@apotonick
Aug 17 2016 09:54
well even that would work
BTW i saw someone asking about views and autoinject, and he was doing having this autoinject includeline in the view class. i was wondering if that is the desired way of using it, @timriley ? in my world, the view shouldn't know anything about user repos?
Tim Riley
@timriley
Aug 17 2016 09:56
It's how we've been doing it. Views prepare the data to pass as locals to the template.
In this way they might sit at across a slightly different "layer" to your cells-based views.
Nick Sutterer
@apotonick
Aug 17 2016 09:56
why is that?
haha, ok, i give up, i was only suggesting reusing what exists and is battle-tested :joy:
how do you prepare those locals in dry-view?

in cells, the goal is to have views such as

%h1
  = header

= avatar
.body
  = body_text

where the cell instance makes it as simple as possible to deliver the data for the logic-less view. that's basically it

Tim Riley
@timriley
Aug 17 2016 09:59
I'm not trying to be obstinate, sorry if it came across that way! Just seemed to take a while to explain the separation of collaborators/input data which is helpful for dry-system-based apps with a lot of "functional objects"
Nick Sutterer
@apotonick
Aug 17 2016 10:00
so, in that gentleman's example yesterday, the code was something like this
class SomeView < ...
  include Container[:userrepo]
i was a bit puzzled why the view knows such specifics such as which repo to use? or is that the whole point?
Tim Riley
@timriley
Aug 17 2016 10:01
That's the point :)
Nick Sutterer
@apotonick
Aug 17 2016 10:02
BTW @timriley it would be quite easy to make cells "reusable" where call would accept runtime params and new would support auto-injection
ok, but let's say you had a JSON endpoint and a HTML one, both "presenters" would have to know about the userrepo ?
or would it - ideally- be the same "view" but different... templates?
Tim Riley
@timriley
Aug 17 2016 10:08
We've handled the different formats so far by looking for a template with a different file extension. So the same view object.
Nick Sutterer
@apotonick
Aug 17 2016 10:09
and what if JSON needs other decorations, e.g. avatar url and not the image tag?
or, the url instead of just the path?
Tim Riley
@timriley
Aug 17 2016 10:15
🤔... I guess I'd provide objects to the template that have both those things available, so the templates can use what they need.
Nick Sutterer
@apotonick
Aug 17 2016 10:18
really?
Tim Riley
@timriley
Aug 17 2016 10:19
/me feels like he's being trapped 😬
Nick Sutterer
@apotonick
Aug 17 2016 10:19
because what we do is:
  1. decorate objects with generics e.g. human_readable_name or something that's needed in both.
  2. the cell will provide HTML specific decorations, which are usually way more complex than documents
  3. representers will do the JSON formatting
Tim Riley
@timriley
Aug 17 2016 10:20
Happy to check out how cells handles this.
I wouldn't use dry-view for JSON
Nick Sutterer
@apotonick
Aug 17 2016 10:20
well we concluded that HTML views are usually way more complex than JSON documents, so cells are more powerful for a reason. for JSON/XML we have representers
you wouldn't use dry-view for JSON? so the user_repo dependency would be defined in two places?
what i want to learn is how you guys use the DI stuff
BTW not trying to corner @timriley hahaha
Tim Riley
@timriley
Aug 17 2016 10:28
You could use dry-view for JSON if you found a nice way to build the JSON response in a template.
Nick Sutterer
@apotonick
Aug 17 2016 10:33
ok, i understand that, but currently, you'd need to define your dependencies in two places? one for HTML one for JSON?
can you show me how the view prepares the locals for the template, with a quick example?
Piotr Solnica
@solnic
Aug 17 2016 10:40
@apotonick there’s nothing wrong in having a dependency used in more than one place, although we could use inheritance in views to reduce duplication (not sure if dry-auto_inject supports inheritance yet though, @timriley ??)
Tim Riley
@timriley
Aug 17 2016 10:41
I'm on my phone atm (and about to put it away!), but you can check out any of the view classes in the icelab/Berg project (look in apps/main/lib/main/views)
@solnic it supports it 💪🏼
And yeah. A dependency used in more than one place is just a good example of reusable logic being appropriately extracted, right? ;)
Nick Sutterer
@apotonick
Aug 17 2016 10:42
ok, but where does the logic sit to retrieve the actual object(s) from the repo?
Piotr Solnica
@solnic
Aug 17 2016 10:43
@apotonick repos are collaborators, so view objects just ask a repo for data, and it can whatever needs to be done with that data, decorate or something etc.
Nick Sutterer
@apotonick
Aug 17 2016 10:44
how would the view ask for the data?
Piotr Solnica
@solnic
Aug 17 2016 10:45
user_repo.gimme_some_data :)
Nick Sutterer
@apotonick
Aug 17 2016 10:46
ok... but then the gimme_some_data is redundant in the view and the json-view
that was a question
i should've added a ?
Piotr Solnica
@solnic
Aug 17 2016 10:50
use inheritance
Andy Holland
@AMHOL
Aug 17 2016 12:01
Seems strange to me for the view to depend on repo too
Andy Holland
@AMHOL
Aug 17 2016 12:18
I'd have a transaction return the data then decorate it in context-specific way and pass to the view
Otherwise feels like mixing view/controller
But maybe this is why I always have the "too many layers" problem lol
Nikita Shilnikov
@flash-gordon
Aug 17 2016 20:26
@solnic this https://github.com/dry-rb/dry-types/blob/master/lib/dry/types/builder.rb#L9 does not work when your sum type consists of more than two variants, like Types::Strict::Bool | Types::Strict::Int | Types::Strict::String
I get Sum instead of Sum::Constrained
should I fix that?
Piotr Solnica
@solnic
Aug 17 2016 21:25
@flash-gordon yes please? :)
Nikita Shilnikov
@flash-gordon
Aug 17 2016 21:43
k :)