00:00:19.259
okay hey it's really great to be here so
00:00:24.550
I'm Piazza Utah my name is so rude because I come from clock off it's a
00:00:30.489
beautiful city in Poland if you've never been to Poland it's real beautiful so I
00:00:35.590
invite you to come we have some rubik conferences as well with also beautiful
00:00:40.629
mountains so it's a really nice country so really quickly about me on a ruby
00:00:48.850
developer you can find some of my open source projects on github and follow me
00:00:54.190
on Twitter I'm so linked everywhere so if you wanted to say you had one job I
00:01:00.190
actually don't I have three so I'm a part of a company called powwow at a
00:01:06.910
Polish Norwegian consultancy I'm also working for victorious which is a good
00:01:13.510
hosting platform that you can host yourself and by the way we were moving to docker it's like eighty percent done
00:01:20.580
I'm also working for a norwegian company called evo which is a chain of fitness
00:01:26.170
clubs with a huge infrastructure built in rails so like before i start i wanted
00:01:32.260
to talk a little bit about like my experience this ruby developer so that you can know where I'm coming from with
00:01:38.560
all this stuff so I started working as a ruby developer seven years ago and in
00:01:44.740
2007 we were mostly working on startups right so every project was greenfield
00:01:49.770
everything was really great right we were using rails we were writing a lot of Ruby code and everything was smooth
00:01:56.440
and just beautiful right but at some point some of those startups actually
00:02:02.050
succeeded right so suddenly we started working on huge a couple of years old
00:02:08.369
Reyes apps and at some point it became a problem right it started to be
00:02:14.530
really difficult to maintain those projects and I started to think why is
00:02:21.069
it so hard to maintain a big rails application right what's the cause of this problem and initially I thought
00:02:29.170
that yeah maybe we could use different patterns maybe we could just use different libraries but really what
00:02:38.709
we've been doing for the last couple of years seems to me like not solving the problem but working around the problems
00:02:45.190
that we have and what I realized is that the cause of this problem is just complexity that we have and all the
00:02:52.450
tools that we are using are extremely convenient so that we can move really fast but we don't think about the
00:02:59.290
complexity that we pull in when we start depending on external product of the gems so when we create a new race
00:03:05.920
project even if you don't include any additional gems it's already a lot of
00:03:11.319
complexity that we have without even writing any code so then we start to
00:03:17.860
actually write some code so we build even more complexity on top of already existing complexity right so it's
00:03:24.459
something we don't think about on a daily basis so today I want to talk about convenience versus simplicity and
00:03:32.310
even though the title of this talk may seem to be a little bit abstract I
00:03:37.420
actually try to make it more concrete however I'm going to start by some by
00:03:44.590
explaining some of those abstract terms so convenience when you look at the
00:03:52.500
definition in dictionary it says that convenience is the state of being able
00:03:59.350
to proceed with something without difficulty right and when you think about it it's exactly what happens when
00:04:05.709
we use our convenient tools like rails and true to remember this one this is
00:04:13.600
from screencast we're dhh showed how to build a block application in your rails in 15 minutes it's pretty famous you
00:04:20.169
probably sell it so this is this is it this is the convenience all the things
00:04:25.330
that we're not doing all the things we're not thinking we're just preceding really quickly with
00:04:30.910
our tasks we're accomplishing our goals really quickly without thinking much about the problems that they're that
00:04:36.670
we're actually dealing with because a lot of those problems are solved by the libraries and frameworks that we are
00:04:42.400
using so on the other hand we have simplicity and again when you look at
00:04:47.860
the definition it says simplicity is the quality or condition of being easy to
00:04:53.320
understand or do and it's a little bit tricky because we often say that
00:04:59.260
something is convenient and like immediately connected with something that's simple and it might be a little
00:05:06.400
bit confusing because you see something that is simple your think okay that's convenient it's simple i can simply just
00:05:11.860
use it and it works but you don't really think about what's inside right so what
00:05:19.600
usually happens is that a lot of libraries and frameworks that are super convenient and really simple to use come
00:05:26.770
with a lot of internal complexity something that we just don't think about because we don't see it so it's not our
00:05:34.780
problem right so when it comes to
00:05:40.120
complexity and ways of dealing with the problem of complexity what program is
00:05:46.540
usually do is to focus on separation of concerns if we have a huge problem which
00:05:54.280
is real difficult to solve we try to like split it into smaller pieces into smaller problems and solve them
00:06:00.940
individually and what I've noticed in
00:06:07.090
the Ruby ecosystem that is probably inspired by by rails we often focus on
00:06:17.290
convenience first we often focus on all the fancy dsl's and the convenience that
00:06:23.080
that should come right from the start so when you look at for example active
00:06:31.150
record right it's a great example of a convenient library a library library
00:06:37.270
that solves a lot of different problems the problems that are really hard to solve by the way so when you look at a basic model the
00:06:44.919
basic active record model it's just an empty class right and you might think
00:06:50.139
that it's super simple right because it's just a class and you don't even have to write anything except defining
00:06:56.079
the class to get a lot of functionality for free if you want to create something
00:07:01.679
and persist it in the database it's also very simple just one method called
00:07:07.809
passing programs and you're done even wanna even if you want to do something more fancy like find something fetch
00:07:15.339
something from the database loaded into memory and then do something with it and
00:07:20.349
save it back to the database it's still super simple you just call like three
00:07:25.659
methods here right so you might think it's all so simple I don't need to learn
00:07:32.709
a lot I'm I'm just reading API documentation for like three minutes and I know what to do so you think yeah
00:07:39.729
that's simple and really I don't think it's simple and the reason why it's not
00:07:45.429
simple is that there are a lot of things going on under the hood and even though I don't see them they do exist and
00:07:52.659
that's why I prefer to use the word convenient because it is all very convenient but it is not simple there is
00:07:59.619
no simplicity here there's a lot of internal complexity it's just we don't see it when it comes to separation of
00:08:09.849
concerns if we look at this create method and think about what's actually
00:08:17.169
going on we will realize that we are
00:08:22.479
dealing with things like data coercion which is a huge problem to solve by the
00:08:28.329
way there are a lot of really nasty things that you need to deal with when
00:08:34.809
you want to have coercion setting default values this is also something
00:08:40.179
that happens under the hood you might not think about it but it exists we do
00:08:45.759
things like validation and validation is also a really big problem to solve and eventually we we do interact with the
00:08:52.899
database and interacting with the data is also a huge problem to solve right and this is like the basic stuff that
00:08:59.800
that happens under the hood and if you're less lucky you could have things
00:09:07.329
like business logic hidden in life cycle hooks all the before say before validate
00:09:13.180
all this stuff this is super complicated and we do that we also do things like
00:09:19.810
handling nested data structures using except nested attributes for which is also super complicated thing to deal
00:09:26.800
with we also do things like data normalization to custom attribute writers and plenty of other stuff so
00:09:34.899
this is a lot of complexity and we tend to hide it in one place but it's just
00:09:42.040
not a good thing to do so when if we want to talk about separation of concerns in this context we might look
00:09:51.339
at it in a way where we can use separate objects to handle separate concerns so
00:09:57.910
what I tend to do these days is to process parameters using a separate
00:10:05.079
object validate things using a separate object and handle persistence by
00:10:10.720
separate separate object as well and whenever we talk about separating concerns and whenever we talk about
00:10:16.930
using separate objects there's always at least one person who would say something like well that's more complicated right
00:10:23.139
I usually have one object now i have three and i don't think it's a good way of thinking about it because separating
00:10:30.339
concerns is actually something that leads to simplicity even though you have more objects you still have better
00:10:37.180
encapsulation and those objects are smaller and it's just easier to work with them and one of the benefits that
00:10:43.990
we have here is that we can always come up with a higher level abstraction something that is more convenient and
00:10:50.529
just encapsulated and have just one method and we have exactly the same convenience but internally it is
00:10:56.649
separated internally we have separate separate objects having separate concerns so this is like the benefit of
00:11:04.860
separating concerns where you don't have to you not necessarily
00:11:09.870
have to be concerned about many things you can have a system that is built on
00:11:15.810
top of more primitive tools but it could expose a very convenient interface but
00:11:21.090
once some of those concerns become your problem when something is is your
00:11:26.310
concern for example when you actually want to deal with corrosion on your own
00:11:31.440
or validation on your own you always have a way of using a separate object
00:11:37.970
whereas in case of libraries like active record or many other gems written in
00:11:43.710
Ruby where a lot of things are handled by by just one thing you just don't have that choice because there's no separate
00:11:50.520
objects there are no separate objects that would handle separate things so you just cannot use them separately so the
00:11:59.760
next thing as a data and behavior this is also an interesting subject because
00:12:05.910
so Ruby is an object-oriented language obviously so whenever we talk about object-oriented design we like to say
00:12:12.570
things like yeah it's all about objects and sending messages right or behavior oh and I think that this whole movement
00:12:20.550
with with design driven development we had a talk yesterday about it it is a
00:12:26.700
nice way of thinking about software but quite often it actually leads to
00:12:32.100
something that we could call accidental complexity we may quite often introduce
00:12:38.970
complexity that it's not really needed just because it feels like good to think
00:12:44.880
about objects and the way they correspond to I know some real world concept like for example if we have an
00:12:52.380
application some kind of a system running and it it has users right so it's like natural for us to think about
00:12:59.600
having a user object because well it will represent it will represent the
00:13:05.220
users of our system so it feels like natural to to to design our system like
00:13:10.470
that but when we do this and when we focus on behavior so much we may often
00:13:16.860
use objects that are simply to be and it's also really something really a popular to do
00:13:27.450
in Ruby and especially in rails to use active record for everything and as I
00:13:35.519
said if you have a user instance and we have users in the real world and we want
00:13:41.459
to have something like displaying full name it feels natural to just add a method called full name because well our
00:13:47.100
our users know their full names so our object should know it's filling right so
00:13:53.010
we do that but we but we don't think about what's the actual requirement and if our feature is too I don't know
00:14:00.620
display a list of users with their full names in some kind of user interface then the only thing that we need is the
00:14:07.110
data and something really simple that knows how to display a full name or how
00:14:12.420
to return a full name right so what we do here is that we already have an
00:14:19.560
object we already have a model and represent users so which is convenient to just just put methods there just just
00:14:27.000
expand its behavior because it feels natural but what I what I'm usually
00:14:33.149
doing these days is to just focus on the most basic stuff on what's really really
00:14:39.329
needed for the system in order to work so the data is really important all we
00:14:47.370
need is to just get the data and have some kind of an object that returns the
00:14:53.220
full name so it is like the essential part here to have just those two things
00:14:58.800
in order to accomplish our task this is obviously a very simple example but it
00:15:04.680
like illustrates the philosophy here and you know using this object is still very
00:15:10.440
simple so um this is pretty much what
00:15:16.820
convenience is well this is like a some kind of a crappy coffee maker but it's
00:15:22.560
convenient right you just press the button and there goes coffee but what I really prefer is this this is v60 I had
00:15:30.209
coffee here from v60 it was awesome this is super super simple very basic tool and it
00:15:37.440
makes an awesome coffee and this is pretty much the sense of the essential
00:15:42.779
stuff you focus on what's really really important and you reject everything else I would even I would even say that
00:15:50.430
sometimes it makes sense to be minimalistic what when you big when
00:15:57.000
you're when you are minimalistic you're you're just reducing complexity and
00:16:02.150
you're just using just the thing that you need nothing else so another
00:16:09.360
interesting thing about data and behavior is similar ability which which
00:16:14.940
is also a little bit weird since Ruby again it's an object-oriented language so we are used to relying on mutable
00:16:21.210
state however mutability is really
00:16:26.240
something that can bite you and be very problematic and here's a very simple
00:16:32.040
example so we have our presenter object it receives some data hash and the fact
00:16:39.930
that this data hash can be changed by something else something external it can
00:16:46.350
actually cause our presenter instance to just be broken and this is absolutely terrible it's just such a basic thing
00:16:54.180
that we do and it can break our code I mean what's the point of doing that so
00:16:59.790
really when it comes to immutability when we're dealing with the data I would
00:17:05.490
really encourage you to just think about making the data structures immutable in
00:17:12.209
a ruby we do that using freeze right unfortunately if we have nested data
00:17:18.240
structures like this data hash we might want to use some external tools tools
00:17:24.360
like ice nine which is a gem that gives you this crazy method called Dupri's
00:17:29.960
which will actually take this hash and freeze everything like deeply so if we
00:17:38.130
try if you try to change it in place like mutated in place it will it will
00:17:43.620
raise runtimeerror all right this is a little bit crazy obviously
00:17:48.750
Ruby but and it's slow and it's actually really slow but for the data structures
00:17:57.000
I'm actually using it and it actually makes my code much more simpler and I
00:18:02.280
feel more confident when I when I'm relying on data structures that don't change another interesting jam that you
00:18:10.200
could use when it comes to immutability is adamantium which is even more crazy
00:18:15.620
it is a gem that makes your objects immutable also by deep freezing them so
00:18:24.570
when it comes to freezing data structures it's one thing but when it comes to freezing all your objects it's
00:18:32.700
a completely different story so I actually started using adamantium a
00:18:38.190
couple of years ago initially when we were working on a date and upper to
00:18:44.850
which is now called Rome we started with like a very clear separation where we
00:18:52.020
have commands and you have Curie methods and it worked great but then then cop
00:18:58.550
maintainer of data mapper and also developer in Rome suggested that maybe
00:19:04.770
we should try to make it more hardcore and actually start to use immutable
00:19:10.380
objects like all the time so he created adamantium to like enforce this style
00:19:15.780
and I get really intrigued by that and I thought well this is a little bit crazy
00:19:21.420
but I'm gonna try right so I started doing that and really it was tough it
00:19:27.810
took me like few months to just wrap my head around this concept and just change my style of writing code so that I will
00:19:34.530
be creating objects that won't have to change and initially I hated it but I
00:19:40.680
really had this like this feeling that it will pay off like at some point I
00:19:46.650
will get it and it will benefit will be beneficial and it actually started to
00:19:52.410
make sense at some point and after a few months I noticed that my code is now way
00:19:58.679
more simpler and I'm actually way more confident with everything that i do because i don't
00:20:04.080
have mutable state so adamantium works more or less like that so if you have a
00:20:11.610
class and you include adamantium them you won't won't be able to change
00:20:18.150
anything inside this this object the instance of this class no more no matter
00:20:23.820
how deeply you will go how deep you will go it will raise an error but it's super
00:20:30.000
slow it's extremely extremely slow so under the hood it's it's using the the
00:20:36.300
ice nine gem that i showed you before but I would actually like to encourage
00:20:43.380
you to just play with it as the next exercise and see how far can you go with it it's a mind shift but I think that
00:20:51.030
it's actually worth the effort because it might change the way you think about
00:20:56.070
writing code it worked really great for me I'm still using adamantium in my some
00:21:01.740
of my open source libraries and in some places in in in in my projects for my
00:21:07.680
clients however it is slow so whenever I see that it slows down things too much I
00:21:14.280
would just drop it but the trick is that after few months of writing held in this
00:21:20.430
style I actually so got used to it that I'm currently I'm just unable to design
00:21:26.820
something when objects are mutable I just my brain no no longer works like
00:21:31.830
that I just created objects and they won't change they don't expose an interface where you can mutilate them I
00:21:38.070
just mind shift seriously so this is
00:21:43.140
something that it's also related to convenience and simplicity because a mutable state is actually convenient
00:21:49.710
because you don't have to think about like you don't have to make many decisions up front you just create some
00:21:56.160
objects and then later on in run in run time they may or may not change depending on the context maybe I will
00:22:02.430
have to do something extra to set some I instance variable or not it's just more
00:22:07.530
convenient whereas objects that cannot change are less convenient but you act
00:22:13.920
Chile achieve simplicity in your code so
00:22:19.470
it is worth the effort I highly recommend that um so next part is about relational model this is a huge subject
00:22:29.840
when we think about when talk about relational model we usually think about relational databases and the trick here
00:22:36.630
is that it's not really about the databases it's not really about SQL
00:22:42.470
because relational model is actually something that we can use to structure our data and recently I read a paper
00:22:50.010
called out of the tar pit which is which talks about dealing with complexity and
00:22:56.630
one of the biggest parts of this paper is about relational model and how it can
00:23:03.270
simplify our systems so the definition
00:23:08.790
that they have is that the rule the relational model has despite its origins nothing intrinsically to do with
00:23:14.820
databases rather it is an elegant approach to structuring data and means to money for manipulating such data and
00:23:20.820
a mechanism for maintaining integrity and consistency of state so when we talk about relational model we actually talk
00:23:28.710
about how we structure our data how our data should look like in our system
00:23:34.530
we're not talking about how it's going to look like in a database it's a separate concern and also it gives us a
00:23:42.750
way to deal with the data in an in a structured manner so when it comes to
00:23:48.210
Ruby and rulership relational model we actually have some pretty awesome libraries so if you want to if we want
00:23:56.640
to use relational model in in Ruby for example we have a library called axiom
00:24:01.730
this is like the foundation for Ruby object mapper and this library gives us
00:24:06.900
a an implementation of relational algebra and with axiom you can define
00:24:12.840
relations and as Luca said yesterday during his dog relations are just sets
00:24:19.770
with tuples and nothing else it's it's a really really simple concept and when we want to define a structure of a relation
00:24:26.820
we simply define its header and a header just defines what attributes a relation has and what data data types we use so then
00:24:36.210
we have a an interface for a manipulation so for example if we have
00:24:43.820
relations users and tasks we can simply insert data into those relations and by
00:24:50.880
the way this this is immutable so users
00:24:55.950
dot insert returns a new instance of users relations so the previous one is not being changed then we can use
00:25:03.720
relational operations in order to create other relations so we have things like
00:25:09.390
join rename or streak project all this stuff is there and then we can simply access data so this is a really simple
00:25:17.340
concept you just have a set of tuples nothing else and a bunch of methods that you can use in order to manipulate the
00:25:23.250
data and access the data one of an interesting things one of the
00:25:29.970
interesting things is that you can actually do some crazy stuff like join two relations and then insert data into
00:25:35.760
those relations and axiom will actually distribute if we were you if you are
00:25:40.950
using an SQL database and you have two tables it will actually distribute the rights to the insert methods sorry
00:25:47.460
insert statements into separate tables so this is pretty cool and it's because
00:25:53.700
there is this concept of data independence in relational model and which says that it is a clear separation
00:25:59.220
that is enforced between the logical data and its physical representation so
00:26:05.610
this is pretty much what what Ruby object mapper is doing we have a logical
00:26:10.620
structure of our relations that we define in our application level and the
00:26:16.890
way it is actually stored in a database is something completely completely different handled by a separate layer
00:26:23.600
mmm Epsom handle handle handles that by
00:26:28.980
using adapters for databases so a really
00:26:35.390
huge concept that we're experimenting with is using relations
00:26:42.050
first class citizens it isn't she this is an interesting concept and what we
00:26:49.650
usually do these days in Ruby at least is that most of the over amps are using
00:26:55.410
active record pattern so like the the first class citizen in our in our system
00:27:00.600
is is a model right it is a class that gives us a curie interface so we have
00:27:06.570
this model and we run some Curie's to get the data and even though for example
00:27:12.510
here we have a scope called active so if we use the the Cure interface of active
00:27:18.870
record we do get a relation back although the relation is not the first class citizen you're in our system the
00:27:25.560
model is and the instance instances of this model also work as the first class
00:27:32.430
citizen in our system so the major
00:27:38.040
difference in philosophy here is that we would like to put relations in front and
00:27:44.100
when I say relations I simply mean the data right because relations is just
00:27:49.830
data so like the most basic implementation would be to have a
00:27:55.680
relation registry where internally we define relations that we need in order
00:28:01.350
to build other relations that we will expose publicly for our application so
00:28:06.420
with we don't think about running Curie's in our application we're thinking about the data we're thinking
00:28:11.490
about what data do we need and how it is being fetched from the database is just
00:28:16.920
completely completely separate concern so here we just create a relation registry and we have access to active
00:28:23.520
users and active users it's a relation that is the first class citizen in our
00:28:28.830
system and it's just data so the reason why this concept is at least should be
00:28:39.330
better is that we achieve better composability and better encapsulation and by composability I mean if we're
00:28:48.570
using relations and just relations we can combine them compose them to create
00:28:53.760
other relations and the order in which we are doing that is is just not important and not relying
00:29:01.210
on order is one of the things that we should do in order to reduce complexity and another thing is its encapsulation
00:29:08.110
when we are using relations we're talking about the data we're talking about what data we need we're not
00:29:13.540
talking about how we fetch the data so that's that's a huge difference so if we
00:29:21.610
take a look at a at an example where we want to find all the users without task
00:29:27.520
so we have users and they have task you might want to find all the users with no tasks so inactive record we would like
00:29:33.910
to use John but this won't work because this produces an inner join so what we
00:29:39.429
need to do is to just use an SQL a partial SQL and using a left outer join
00:29:45.929
yesterday we saw how we can do this with ariel with an object-oriented interface
00:29:52.350
but still we are talking about running and Kure here we are talking about details like what kind of a joint we
00:30:00.880
should use what kind of keys we are using in the on clause and all this
00:30:10.150
stuff that is just specific for a database and my experience is that when
00:30:15.730
i'm working on a bigger project where i have a lot of lot of color a lot of
00:30:24.720
methods that return puri object or
00:30:29.980
scopes we call them scopes I simply lose confidence pretty quickly I had many
00:30:36.370
times I had a situation where it turned out at some point that all the crazy chaining that we did in some place of
00:30:43.780
our system actually returns wrong data which sometimes it's not a big deal but sometimes it can be pretty huge bug
00:30:51.480
since we're exposing data that are for example that should be for example are
00:30:56.590
hidden so it's a big problem and when it
00:31:01.780
comes to relations as first class citizen the concept here is that we are not composing Curie's we're composing
00:31:07.030
relations and I know that it made sound it might sound a little bit confusing for you
00:31:12.620
since as I said active record curing methods return relations as well but we
00:31:18.620
are still thinking in terms of curious not in terms of relations and the difference is that when we combine
00:31:27.289
relations we use relational algebra to do that so we use relational operators
00:31:32.419
to do things and it is again it is like basic set theory we're just using basic
00:31:39.019
operations on on set that has some tuples and that's it so if you want to achieve the same thing find all the
00:31:45.169
users without task we're just using the difference operator or something that
00:31:50.179
even looks looks nicer just just uh Elias which is a minus so we say all the
00:31:55.549
users minus the ones with tasks which obviously gives us users without tasks and the trick here is that all the
00:32:04.399
relations if we are using an SQL database we can translate all the relations into an SQL query currently
00:32:14.440
the SQL generator in axiom can do pretty much everything although performance is
00:32:21.110
obviously a problem so we're not working on an optimizer that would make sure
00:32:27.169
that we are running a curious that are efficient so all those ideas we're
00:32:37.279
trying to incorporate them within this project called Ruby object mapper I mentioned it before it started started
00:32:45.139
as the second version of data mapper project but eventually we realized that it's just something completely new so we
00:32:51.830
decided to create a new project give it a new name and also initially we thought
00:32:57.200
that we're going to implement the data mapper pattern as described by Martin folder however recently we started
00:33:03.409
thinking about doing some things differently like using relations of the
00:33:08.750
first class citizen so the major focus in the project is is to focus on
00:33:14.509
relations which means to focus on just the data this is our primary
00:33:21.290
turn right now to create an interface that gives you access to the data which
00:33:27.530
is as simple as possible so that working with the data is just trivial and we
00:33:34.610
also want to want to really achieve clear separation between the database structure and your logical structure
00:33:41.870
that you have in your system and another big part of Ruby object mapper is
00:33:47.440
mapping to objects which is like the core one of the core parts of the data
00:33:52.820
mapper pattern so we have data in the database and then you want to map the data to some objects so initially we
00:33:59.360
thought that this is a huge thing in the project but to be honest right now we're
00:34:05.660
thinking that yes sometimes we might want to map things to something more sophisticated but in many cases we can
00:34:12.620
just use the data tuples and that's it so the next part is is just simplicity
00:34:19.100
we're trying to we're trying to narrow down the interfaces as much as possible we want to have just one way of doing
00:34:26.660
things which is a little bit against the Ruby philosophy but we just disagree
00:34:32.750
with that so we're trying to have for example for all things like creating
00:34:39.919
data we just want to have one interface we don't want to introduce many
00:34:45.320
interfaces just because we want to have some optimism ization for for a database
00:34:50.390
right like an active record you have methods like update attribute update
00:34:56.450
attributes and other things that that are there just because you sometimes want to you want to use them because of
00:35:02.450
performance right so we're trying to avoid that and we're trying to move the optimization to a separate layer where
00:35:10.270
an efficient cube SQL query will be generated and so when it comes to
00:35:17.960
defining logical schema in Ruby object mapper this is pretty much a DSL on top
00:35:24.230
of axiom which is which is also following the philosophy where we're
00:35:30.860
focusing on building small tools that are then used I some higher-level tools that are just
00:35:36.660
a simple wrappers that simply expose a DSL that is convenient right however
00:35:44.430
Rome itself is pretty that simple internally so in Rome you can define
00:35:51.300
relations in a pretty pretty similar way as you do with axiom and one of the
00:35:57.720
ideas that we have right now is to have ability to define to define which relations will be private which means
00:36:04.410
that they won't be accessible within your app they are only there in order to
00:36:10.290
create other relations that you will expose for your app which we believe
00:36:17.460
should should give better encapsulation so if you want to define external
00:36:26.190
external relations or public relations you can just define them and like that
00:36:33.210
without passing the internal true argument and you have access to all the
00:36:39.690
relations that you define before and you can just combine them however you want using relational algebra operators and
00:36:46.950
then Rome will simply expose everything that you defined so in your app you only
00:36:53.160
creating Curie's you won't be writing things that are tightly coupled to the structure of your database you will be
00:36:59.160
simply accessing the data and important part here is that relations should be
00:37:04.290
context-aware which means that here we have users task relation which returns
00:37:11.310
all the task for a particular user so our context here is that we need the
00:37:17.400
user ID so this is one of the requirements and it will work like that
00:37:24.420
so you will simply pass in the user ID and you will get the data back so this
00:37:29.610
is what we and this is this is the major difference because what we usually do is that this part here in inside this blog
00:37:37.350
this is this is what we would usually right inside our application right like in the controller or somewhere else
00:37:43.500
right it's it's available so we do that even though like the best practice is to
00:37:49.240
your scopes etc but the truth is if something is available then you're going to use it right because it's just you
00:37:55.600
know it's simple it's conveniently we're going to just write it without thinking too much about it so this is like the
00:38:02.619
major difference here um so the the next big part is is mapping data to object
00:38:07.930
but as I said we're kind of changing our minds and and right now we're thinking
00:38:13.420
that mapping is not such a big such an important feature but it can be helpful
00:38:20.500
it can be just handy so we have we have something like a mapping which is a way
00:38:28.210
of defining how you want to map relations to some other objects so Rome
00:38:34.090
will create entity classes for you and it will it will just create a way of
00:38:42.570
instantiating those those entity classes using the data from from relations so
00:38:48.940
this is an example of a basic attribute mapping so it would generate it would
00:38:54.640
generate a task entity and it will it will return entities like instances of
00:39:02.109
this entity class by using the attributes right we also support
00:39:08.020
something like using embedded values so you will be able to create aggregates so
00:39:15.280
here we would have a task entity that has a title and it also has a user
00:39:20.859
instance and it will like automatically generate those classes for you and and
00:39:28.260
yeah because what ya one thing that I forgot to mention is that you in data
00:39:36.310
mapper pattern you can't really have like dynamic things so in active record you do things like user first and then I
00:39:43.450
don't know dot tasks right here you you have to define it up front because once
00:39:49.060
you start accessing the data it already needs to know what will be instantiated and once it's it's nan Chi ated it
00:39:55.240
doesn't have access to persistence layer because it's separated so that's like a major difference between active
00:40:00.549
datamapper approach yeah so the last part is just simplicity even though like
00:40:07.359
the whole Rome project is it is complicated because it's it's it's a lot
00:40:12.999
of different problems however we're trying to solve them using separate libraries so we have axiom we have we
00:40:19.179
have optimizer we have more for for mapping all this stuff is there so that
00:40:25.239
ROM will simply use those tools and just expose the dsl on top of those tools so
00:40:32.709
the focus is on simplicity even though we have many many libraries involved we
00:40:38.109
are still trying to achieve a very consistent interface so that it will be
00:40:44.469
just simple to use so to wrap this up
00:40:49.529
Rome will give you a way of accessing the data you won't be thinking in terms
00:40:54.849
of relationships re in terms of Curie's you won't be thinking about your database columns whatever you will be
00:41:00.969
just accessing relations and you will define those relations inside your logical schema definition it will give
00:41:07.420
you a simple way of mapping the data to some other objects if you want that however we think that in many cases you
00:41:15.400
will be happy with just the data we will also want to have a simple interface for
00:41:21.609
inserting data so there's no point in creating I don't know a user instance in
00:41:28.719
order to do to to save its data using data hash is all you need and we also
00:41:35.019
want to support something like using the relations that you defined to manipulate
00:41:40.359
them so you can for example join many relations as a context for for a
00:41:49.209
persisting a nested data structure and the system will distribute the individual operations due to two
00:41:55.719
separate tables for you yeah so embrace
00:42:01.509
simplicity and convenience can come later you can always look at things later and and see how we can simplify
00:42:08.199
stuff from the point of view of a user that this is using your interfaces
00:42:14.350
I i don't think that focusing on convenience so much right from the start is a good strategy yeah and that's it
00:42:21.940
thank you
00:42:30.549
thanks Peter any questions for him so
00:42:38.329
one question I've been walking around and asking different companies and
00:42:43.730
developers about how far they go with this with approach you describe and most
00:42:51.650
of you of them are pretty happy with a detective records and they are maybe
00:42:57.230
using additional use cases layer but for all the staff they are happy and do you
00:43:04.069
have examples and maybe you have your own experience when you should go that
00:43:09.530
far with operational concerns when you develop a bail application I haven't
00:43:18.799
written any application which would fully be based on those concepts I'm
00:43:26.000
using some of those concepts in some places in my applications and really happy with those Martin one of the guys
00:43:33.980
from from the team is right now working on an application where he's using all this stuff he implemented most of it
00:43:41.780
already in a separate project we're now collaborating together to get all this
00:43:47.569
stuff into Ruby object mapper and he's extremely happy with this approach he's
00:43:55.220
been working on this this application for a few months already it's a lot of code already and he's really confident
00:44:02.750
that this approach really leads to Tuesday to just simplicity but yeah as
00:44:09.890
you said many people are happy with active record many people are happy with the way Reyes works I'm not questioning
00:44:15.230
that race word for me in a lot of cases I'm still happy using rails something
00:44:22.730
that I recently started doing was that I switched to sequel without using its
00:44:29.569
model layer I'm just using its security interface and I'm doing something like I
00:44:35.930
showed you in the slides and I found it to be really great I'm just focusing on
00:44:43.050
on the essential stuff and not I'm just rejecting everything else it feels good
00:44:48.180
but it's it's it's more work it's just more work because I need to write more code but still sometimes it makes sense
00:44:55.620
sometimes it doesn't arise depending on your context but overall I'm pretty confident that if your system is growing
00:45:03.060
then eventually you will appreciate an approach where you're just focusing on simplicity and less inconvenience okay
00:45:10.410
thank you do you think it makes more sense when you startin to write a new
00:45:16.890
application to start with your approach or it's okay to start with regular old
00:45:22.500
regular rails way and then trying to switch trying to refactor I think that
00:45:31.670
depends right if you're working on your own product and you got like better
00:45:38.580
funding than you know then you can do whatever you want and it will probably be great but usually you don't have the
00:45:46.380
situation so right now I would just leverage the power of the tools that I have and then worry about things later
00:45:54.830
Yeah Yeah right now we just don't have the tools that I described today they
00:46:02.400
are not as mature as as Reyes and its ecosystem it's just not there yet and it's going to take years to get there so
00:46:09.420
yeah it's pretty pretty much an experimental stuff so building things on top of experimental software is
00:46:15.600
obviously pricey so yeah okay thank you the last question about the dimension
00:46:21.810
okay try to use it in while you develop and then turn it off
00:46:28.950
when you publish the game Jim or no now
00:46:35.400
I haven't in some of my projects I I
00:46:40.589
just use it and nobody complained but I know that Marcus another guy from the
00:46:47.070
team he had that use case he use adamantium in his project and then he
00:46:52.380
had to turn it off because it was too slow so the slowness you told ballsy it
00:47:00.599
is gonna turn it off yeah yeah okay
00:47:05.730
because you're not freezing everything deeply um just a quick question how do
00:47:15.570
you handle validations like if you're just in general with this scheme yeah
00:47:21.720
I'm having something like a validator object i'm currently i'm just using the
00:47:30.510
active model staff because that's that's the most powerful thing that exists right now one of one of the team members
00:47:39.260
are war I think he's still working on a
00:47:45.540
library called Vanguard which is like a library dedicated for validations that
00:47:52.710
is completely like separated from from everything but there are still some some
00:47:57.720
interesting problems to solve like like you know if your validation procedure
00:48:02.760
requires the database connection and what do you do and things like that but your engineer in general on trying to
00:48:09.599
use the database constraints for for certain things and rely on that you're
00:48:15.119
right now Martin is using the other guy right now he's using an approach where
00:48:22.410
he's just relying on constraints and catching errors from the driver if something wasn't fetched a story wasn't
00:48:28.910
saved he's just fetching error error and producing an error message he's doing
00:48:35.670
that right now and he's still not super confident about like the implementation details but in general
00:48:42.570
like moving towards a different direction where it should work for him
00:48:47.790
pretty well yeah since we're talking
00:48:54.420
about implementing an active model stuff are you mostly using this to generate
00:49:00.750
sequel query statements are you doing any like serializable stuff like JSON or
00:49:06.180
anything with it with what with sequel you're just like generating sequels queries are like statements are you
00:49:12.840
doing anything with like JSON or anything like that but uh no I'm just using it for generating Curie's yeah all
00:49:20.640
right thanks Peter if you guys have any questions after that can look for him
00:49:26.040
because we're running a little bit short on time Thanks thank you
00:49:35.660
you