I will explain this as an Album application problem.
I want to create a new Album but the Artist of that Album is not created yet.
There are 2 solutions to solve this problem:
Create the Artist first, then create the Album
When creating the Album, check if the Artist is created. If the Artist is not created, then create a new Artist and save that information to the Album.
I chose solution 2 and I want to present this using Event Storming.
I don't know how to present the solution correctly in timeline order.
So I have come to this.
I don't know if my solution is correct or not :(
And if it isn't, how to correctly present this?
I would try to make each step explicit so that you also can easily spot what transactions happen to what aggregate. So I assume you see artist and album as separate aggregates (not relevant for now if they live in the same bounded context or not). I would approach it in an event storming session somewhat like this:
--> Create Album (Command)
--> Album Created (Event)
--> Check Artist of Created Album (Policy)
--> Create Artist (Command)
--> Artist Created (Event)
--> Check for Existing Albums of New Artist (Policy)
--> Link Artist to Album (Command)
--> Artist of Album Updated (Event)
For me the policies usually mean: when policy X applies then perform command Y.
With that flow you would also guarantee that only one aggregate is created/modified at a time. Your current approach binds the simple creation of a new album to lots of other responsibilities in one go (e.g. checking if the artist already exists, if yes, creating the artist and afterwards creating the album). I like to get the most essential stuff done as quickly and simple as possible and separate subsequent steps. So here I would consider the creation of the album the highest goal of the user of the application. Because if they haven't created the artist first they obviously like to focus on album creation now more. If the artist entity is created in a second step should then be not of so much concern for the user.
It really depends why your business needs to know that an album has an artist.
On the face of it, I would say that both album and artist, if they are separate aggregates, should be created independently and exist regardless of there being a link between the two.
You do not want to implement referential integrity between aggregates, it is eventual consistency. All should be able to exist without the other, it is just in a state of not having all information.
If you actually want to prevent the album from being created without there being an artist, then there should be a policy in which you will decide to create an album, but this will result in a create artist command, as the album needs an artist first.
If an artist already exists it is as simple as:
Create Album Policy -> Create Album -> Album -> Album Created
When an artist does not exist I would do something like this:
Create Album Policy -> Create Artist Command -> Artist -> Artist Created Event -> Create Album For New Artist Policy -> Create Album -> Album -> Album Created
These make sense when you have manual policies with a user, however if it is entirely automated then you might actually be talking about a single command and you might need to reconsider your aggregates, or at least your aggregate root.
Related
My app is giving user types of news based on the input. For ex: If user is saying what is happening in sports, so I give user sports news in the form of compound card. Now if user is saying that "Show me similar news", so all i need to do is pass the category id of that news to my other file and process that category id to get more same type of news. I am unable to pass the category id.
My news details file is NewsSearch.model.bxb and input i have taken is categoryName, which I convert into id and pass it to my api.
My similar News file is SimilarNews.model.bxb and input is categoryId, which I am supposed to pass to my api to get the same category news.
How to pass categoryId from NewsSearch.model.bxb to SimilarNews.model.bxb?
This is similar to a Continuation. If NewsSearch concept is not marked as transient, you can create an Action SearchSimilarNews that will take NewsSearch as the input. Since this is a followup query, NewsSearch will be available to the Planner from a historical perspective and will therefore be automatically passed into the input.
You may want to look at the Continuation sample capsule for more ideas https://github.com/bixbydevelopers/capsule-samples-collection/tree/master/continuation-for-training
How is it possible to group albums by year?
For example:
2014
- Album 1
- Album 2
2013
- Album 3
I've recently seen that it is possible to group them in the backend using a subfolder-like approach to sort them - but is it also possible to query albums for a specific folder?
I'm currently using this call in my Gallery overview:
[[!GalleryAlbums? &sort=`year` &albumCoverSort=`random` &rowTpl=`galAlbumRowTpl`
&toPlaceholder=`galleries` &showAll=`1` &parent=`6`
&prominentOnly=`0` &limit=`50`]]
<div class="galleries">[[+galleries]]</div>
Currently the GalleryAlbums Snippet doesn't support sorting by year, even though there's a "year" field for the Album object:
However, there's a couple ways to do this.
1. Write your own Snippet
This would be the most performant option, but instructions for this might be out of scope here, so another option might be:
2. Nested Template Chunks
Organize your albums by nesting them under parent albums named after the year. So you'd have an album called "2014" and under that you'd have child albums you want to display for that year.
Then modify your snippet call to include these properties:
&showAll=`0`
&parent=`0`
According to the Gallery documentation, this is what those properties do:
showAll If 1, will show all albums regardless of their parent.
parent Grab only the albums with a parent album with this ID. Remember to set showAll to 0, otherwise it won't work!
Now modify your rowTpl, so that it's something like this:
<li>[[+name]]
<ul>[[GalleryAlbums? &showAll=`0` &parent=`[[+id]]` ... ]]</ul>
</li>
What this means, is that your "outer" Snippet call gets only "top-level" albums, because you specified that the parent attribute must be "0". Then the tpl for each album calls the Gallery snippet again, with the parent property as the ID of the currently iterated Album, thereby returning a list of child Albums. Note in the above code sample, I've omitted the other important properties like &rowTpl, which you would need to populate.
NOTE: I see you're calling your Snippet with the uncached token !. You might get performance gains by caching it, especially if you use an aggressive caching mechanism like StatCache. Granted the GalleryAlbums getList processor utilizes its own cache handler, but there will likely be performance penalties for using a nested Snippet call like the one I've described here.
I'm very new to LocomotiveCMS. I'm trying to do a CMS for an artist agency. The agency represents several artists and each artist will have some pages: bio, agenda, news, gallery, etc. I'd like to have an urls like:
www.example.com/artists/artist_name/bio
www.example.com/artists/artist_name/news
...
I guess I have to create an Artist content type and maybe a new content type for each artist page type and use a reference to the artist in each ones. But I don't know how to get the urls i want.
Any idea ?
Thanks
There is no way to do this right now using the master branch. There is a wildcard branch (https://github.com/locomotivecms/engine/tree/wildcards) that should allow you to do what you want but I have not used it.
I noticed the search result may return multiple albums for a given artist and album, and the albums have the same release year. For example, the search of artist:"Foster The People" album:Torches returns 5 albums, and 4 of them look same (same release year, same album name, same artist, and same tracks of the album) although album uri is different. Can I assume the 1st (top) one is always the most recently added or released?
Thanks,
Probably not. However, order and date added isn't relevant as long as the release year is the same.
You should check the results to see how many tracks are available to the user in each version of the album, as it can vary by region and will often vary by URI. What often happens in our catalog is that multiple versions of the same album are released to different territories but will still show up in search results.
To sum up:
Order isn't important.
You should show the user the album which has most available tracks.
You can see this in our own desktop client too. If you view the artist Rihanna in the client, you'll see a little arrow button just after the title of the album "Talk That Talk". If you click that, you'll see all of the releases of that album on Spotify. The client, by default, will only show you the one which has most available tracks.
In expression engine:
I have a site that businesses can sign up and then sell 1 type of widget. Each business just needs name, widget and price. Then there will be a page that shows all business, with their widget and price.
What is the best way to handle the extra parameters 'widget' and 'price'?
From what I can work out there are two options
1/ Sign up the business as a user in a group with no admin privilages. Add the two custom member fields 'widget' and 'price' for the users. (It may not be called 'member' field, I'm going off my memory). To show these business I then grab the users.
or
2/ Sign up the business as a user in a group with no admin privilages. Add a one custom member field called 'id'. Then create a 'business' channel and to that channel add the custom fields 'name', 'widget', 'price', 'user_id'. Then link the instance of the business channel to the user with the 'id' property. When I want to show these business I grab the details from the channel.
Sorry if this is already answered somewhere. I'm not getting much luck from google, most likely because i'm having trouble phrasing my question succinctly enough.
Thanks
Dave
Dave,
If you're dead set on using users to organize these businesses, then your best bet would be the two custom fields. They're easier to use in templates and you don't have to worry about pulling in the channel data for the item in the custom member field 'id'. That being said, you should check out Solspace's User Module—it'll give you more flexibility with the member information.
Another thought, and depending on whether or not these businesses should be able to edit their widget and price, is you could just make it a channel and skip using users altogether. Using Freeform, you could create a form where businesses add that information, you get an email, and you add the information to the channel you want.
Wes