-
Notifications
You must be signed in to change notification settings - Fork 1
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Aggregate.replay cannot work with required attributes #3
Comments
Thanks for input! class A
include Jouba::Aggregate
end
class B; end A.foo # => Error |
require 'jouba/aggregate'
class Customer < Hashie::Dash
include Jouba::Aggregate.new(prefix: :on)
property :uuid, required: true
property :name
def self.create(attributes)
attributes[:uuid] = SecureRandom.uuid
Customer.new(attributes).tap do |customer|
customer.create(attributes)
end
end
def create(attributes)
emit(:created, attributes)
end
private
def on_created(attributes)
update_attributes!(attributes)
end
end And you'll never be able to call |
thx! i ll look into that in +9h, but the quick fix sounds like we could add hashie extension to ignore undefined attr. thx for your input Have a nice day! :) Grégory Horion
On Fri, May 8, 2015 at 10:08 AM, diegodurs notifications@github.com
|
Had a second look and understood the issue now. Actually think that this is a bug in the Readme and that this kind of domain validation should happen outside the domain, ie in a form object or a command object. Indeed, there is no way we could have data "integrity" enforcement when you base your data on events, like we could have in sql systems where you can add db constraints. Something to keep in mind too though, is that your data input validation might change with the context. This enforce the theory that it's a bug in the readme, not to say, that the specs are green :D what do you think? |
Here would be the fix: class Customer::Create
def self.call(form)
Customer.create(form.attributes)if form.valid?
end
end
class Customer::Create::Form < Reform::Form
property :name
validates :name, presence: true
end
require 'jouba/aggregate'
class Customer < Hashie::Dash
include Jouba::Aggregate.new(prefix: :on)
property :uuid
property :name
def self.create(attributes)
attributes[:uuid] = SecureRandom.uuid
Customer.new(attributes).tap do |customer|
customer.create(attributes)
end
end
def create(attributes)
emit(:created, attributes)
end
private
def on_created(attributes)
update_attributes!(attributes)
end
end Faire question would be: how can i enforce the fact that any user creation in my system will have those UUID? Since this is event based, the only way to "create" a user is by emitting a create event from your Customer domain. So if you write a spec for that to make sure that that even has uuid, you should be safe. |
Jouba allready requires the presence of an uuid :) https://github.com/gregory/jouba/blob/master/lib/jouba/aggregate.rb#L42 So I guess it's fair to not be able to requires attributes on initialization and decouple this by action as you shown. I'm also wondering if it would make sense to validate some invariants after playing events. |
In the documentation, you're using Hashie::Dash to build an aggregate and require the
id
property.Something that I want too!
But this cannot work with the
Aggregate.replay
method since it initialize a new instance without any attributes: https://github.com/gregory/jouba/blob/master/lib/jouba/aggregate.rb#L59Thus Hashie::Dash raises an exception ...
Aggregate.find
has the same problem since it uses thereplay
method.I'm wondering how you would solve this problem.
One option could be: we build the object with the first event in the stream and then replay all events: somehting like
SomeAgg.new(SomeAgg.stream(uuid).first).replay(SomeAgg.stream(uuid))
But I'm wondering if an issue can arise if some procesing is done somewhere in
created
instance/class method oron_created
...Otherwise, if a cache is present, we can easily build the object from the last cache which has the required attributes.
My suggestion is to create a class method called
rebuild(uuid)
and start from there.The text was updated successfully, but these errors were encountered: