Closed andriytyurnikov closed 6 years ago
@andriytyurnikov yes. Have you experienced any issue with that?
@paneq, well, no, just got surprised with it, as touching root directory is quite unusual for rails generators and tools. Thanks for clarification
@paneq , I also wonder if running rails test
would run tests of bounded context, and how it interacts with general rails tools and scripts
@andriytyurnikov Thanks for trying the generator! Just to make sure - what files did it create for you?
@andrzejkrzywda after running rails g bounded_context:bounded_context PlatformCore
I've got platform_core/lib/platform_core.rb
and platform_core/test/test_helper.rb
in a root folder,
not in app/
or lib/
or in test/
- just in the root.
Which is fairly unusual, and surprising and potentially scary in aspects of class-loading and testing with rails scripts. So I've decided to ask
@andrzejkrzywda , I guess, option of creating module manually within /lib
is totally possible for me without generator :D But perhaps current behavior is not what you guys wanted ;)
@andriytyurnikov Yeah, it's all super simple here and I'd say it's still a subject for changes. We're usually OK with having bounded contexts as directories in the main Rails directory, but I agree it's not usual in the Rails world. I'm happy that you tried it and we can have this discussion which place is best, thanks!
@andriytyurnikov
For rspec
flavour we actually do the following:
# spec/identity_access_spec.rb
require 'rails_helper'
path = Rails.root.join('identity_access/spec')
Dir.glob("#{path}/**/*_spec.rb") do |file|
require file
end
which would require spec files from identity_access/spec
and you won't miss it in standard rails + rspec test run.
For test-unit that doesn't happen yet and I agree that might be confusing. It was initially extracted from spec-backed project.
Here are corresponding test cases for the reference: https://github.com/RailsEventStore/rails_event_store/blob/master/bounded_context/spec/generators_spec.rb#L62-L73
@andrzejkrzywda , good that you've created a documentation task. I'll try to contribute, and possibly illustrate potential issues with class reloading from root path. However, rationale behing the very concept of BC is up to you guys, I am just starting with EventSourcing
@pawelpacana, well, I am minitest guy, I'll check out spec and test generators right away.
Closing in favor of #187
minitest ❤️
I believe this can be useful for docs replacement by now: https://blog.arkency.com/rails-components-neither-engines-nor-gems/
@pawelpacana , @andrzejkrzywda I wonder if you guys are open to doubts about current choice?)
Which is fairly unusual
indeed and that's the point for me.
In my opinion the fact that you have a top-level directory is the best mental barrier to actually remember that it is a separate context. Put it in app/ or lib/ does not achieve the same effect, I believe.
However, no professional research has been made. Just a personal gut feeling.
and surprising
maybe not... https://www.youtube.com/watch?v=WpkDN78P884
potentially scary in aspects of class-loading
not really https://blog.arkency.com/2014/11/dont-forget-about-eager-load-when-extending-autoload/ - this part is most simple imho
and testing with rails scripts
This part might require most work to integrate properly.
@paneq , well, big question is: are BCs that independent? Bcoz if they need access to some defined environment (EventStore etc.) which is not injected/abstracted or something, then they are not :)
I distinguish between infrastructure isolation (they can share EventStore, DBs, app server, gems) and conceptual, business isolation.
@paneq , you were right about autoloading of models.
I'll go with plain old /lib
modules though, untill docs are present
👍
I wonder if you guys are open to doubts about current choice?)
Of course! I'm not certain our current suggestion is the best one. Happy to hear other opinions.
@andriytyurnikov Also, we would be happy if you fill out our poll about RES usage: https://goo.gl/forms/ecNpJsL5qM2M8Ls93 :) Thank you and have a great day!
As explaining something to beginner may be useful exercise for documentation writer, I would like to ask @paneq and @pawelpacana for criticism of my understanding of the topic of BoundedContext
.
Following code (may be using existing constants) kinda reflects an idea of Bounded Context
module AccountManagementContext
module Commands
Correct
# Queries::AccountByUUID
# Events::Corrected
SignUp
# Queries::EmailAvialable
# Events::SignedUp
SignIn
# Queries::AccountByEmail
# Queries::IsValidEncryptedPasswordForAccount
# Events::SignedIn
SignOut
# Queries::AccountByEmail
# Events::AccountSignedOut
PasswordResetTokenRequest
# Queries::AccountByEmail
# Events::PasswordResetLinkRequested
PasswordResetTokenSend
# Queries::AccountByEmail
# Events::PasswordResetLinkSent
PasswordReset
# Queries::AccountByPasswordResetToken
# Queries::IsValidPasswordResetTokenForAccount
# Events::AccountPasswordUpdated
end
module Queries
IsEmailAvialable
AccountByUUID
AccountByEmail
AccountByPasswordResetToken
IsValidEncryptedPasswordForAccount
IsValidAuthTokenForAccount
IsValidPasswordResetTokenForAccount
end
module Aggregates # collections of events
Account # (AccountSignedUp, AccountSignedIn, AccountSignedOut)
Activity #(*)
AuthToken # (AccountSignedUp, AccountSignedIn, AccountSignedOut)
PasswordResetToken # (PasswordResetLinkRequested, PasswordResetLinkSent, AccountPasswordUpdated)
end
module Events
Corrected # (account_id, email, ecrypted_password, auth_token, auth_token_expiration, password_reset_token, password_reset_token_expiration)
SignedUp # (account_id, email, ecrypted_password, auth_token, auth_token_expiration)
SignedIn # (account_id, auth_token, auth_token_expiration)
SignedOut # (account_id, auth_token)
PasswordResetLinkRequested # (account_id)
PasswordResetLinkSent # (account_id, email, password_reset_token, password_reset_token_expiration)
PasswordUpdated # (account_id, password_reset_token, ecrypted_password)
end
end
Here AccountManagementContext
is an isolated module of application. Module that governs it's state, as state only may be changed through commands, which use Queries and persist Events (as representation of facts).
While naming convention gives rough understanding of context at hand, and may be used to enforce deeper isolation, as framework may be written in a way that enforces particular constant lookup order or in other ways prohibits creation of Events from outside of Commands module of corresponding Bounded Context (AccountManagementContext
).
Running
rails g bounded_context:bounded_context MyContext
creates files right in project's root. Is it by design?