From 476b2c7f2f57cc2b3bd7a2dca9a0356ed60567f8 Mon Sep 17 00:00:00 2001 From: Pat Hartl Date: Tue, 10 Jan 2023 18:58:44 -0600 Subject: [PATCH] Updated edit action to allow add/remove of many to many relationships --- LANCommander/Controllers/GamesController.cs | 159 ++++++++++++------- LANCommander/Services/BaseDatabaseService.cs | 2 + LANCommander/Views/Games/Edit.cshtml | 130 ++++++++++++--- 3 files changed, 207 insertions(+), 84 deletions(-) diff --git a/LANCommander/Controllers/GamesController.cs b/LANCommander/Controllers/GamesController.cs index 4a0cce9..e9b2d03 100644 --- a/LANCommander/Controllers/GamesController.cs +++ b/LANCommander/Controllers/GamesController.cs @@ -245,56 +245,16 @@ namespace LANCommander.Controllers var game = await GameService.Add(viewModel.Game); if (viewModel.SelectedDevelopers != null && viewModel.SelectedDevelopers.Length > 0) - { - if (game.Developers == null) - game.Developers = new List(); - - foreach (var selectedDeveloper in viewModel.SelectedDevelopers) - { - var company = await CompanyService.AddMissing(c => c.Name == selectedDeveloper, new Company() { Name = selectedDeveloper }); - - game.Developers.Add(company); - } - } + game.Developers = viewModel.SelectedDevelopers.Select(async d => await CompanyService.AddMissing(x => x.Name == d, new Company() { Name = d })).Select(t => t.Result).ToList(); if (viewModel.SelectedPublishers != null && viewModel.SelectedPublishers.Length > 0) - { - if (game.Publishers == null) - game.Publishers = new List(); - - foreach (var selectedPublisher in viewModel.SelectedPublishers) - { - var company = await CompanyService.AddMissing(c => c.Name == selectedPublisher, new Company() { Name = selectedPublisher }); - - game.Publishers.Add(company); - } - } + game.Publishers = viewModel.SelectedPublishers.Select(async p => await CompanyService.AddMissing(x => x.Name == p, new Company() { Name = p })).Select(t => t.Result).ToList(); if (viewModel.SelectedGenres != null && viewModel.SelectedGenres.Length > 0) - { - if (game.Genres == null) - game.Genres = new List(); - - foreach (var selectedGenre in viewModel.SelectedGenres) - { - var genre = await GenreService.AddMissing(g => g.Name == selectedGenre, new Genre() { Name = selectedGenre }); - - game.Genres.Add(genre); - } - } + game.Genres = viewModel.SelectedGenres.Select(async g => await GenreService.AddMissing(x => x.Name == g, new Genre() { Name = g })).Select(t => t.Result).ToList(); if (viewModel.SelectedTags != null && viewModel.SelectedTags.Length > 0) - { - if (game.Tags == null) - game.Tags = new List(); - - foreach (var selectedTag in viewModel.SelectedTags) - { - var tag = await TagService.AddMissing(g => g.Name == selectedTag, new Tag() { Name = selectedTag }); - - game.Tags.Add(tag); - } - } + game.Tags = viewModel.SelectedTags.Select(async t => await TagService.AddMissing(x => x.Name == t, new Tag() { Name = t })).Select(t => t.Result).ToList(); await GameService.Update(game); @@ -307,12 +267,34 @@ namespace LANCommander.Controllers // GET: Games/Edit/5 public async Task Edit(Guid? id) { - Game game = await GameService.Get(id.GetValueOrDefault()); + var viewModel = new GameViewModel(); - if (game == null) + viewModel.Game = await GameService.Get(id.GetValueOrDefault()); + + if (viewModel.Game == null) return NotFound(); - return View(game); + viewModel.Developers = CompanyService.Get() + .OrderBy(c => c.Name) + .Select(c => new SelectListItem() { Text = c.Name, Value = c.Name, Selected = viewModel.Game.Developers.Any(d => d.Id == c.Id) }) + .ToList(); + + viewModel.Publishers = CompanyService.Get() + .OrderBy(c => c.Name) + .Select(c => new SelectListItem() { Text = c.Name, Value = c.Name, Selected = viewModel.Game.Publishers.Any(d => d.Id == c.Id) }) + .ToList(); + + viewModel.Genres = GenreService.Get() + .OrderBy(g => g.Name) + .Select(g => new SelectListItem() { Text = g.Name, Value = g.Name, Selected = viewModel.Game.Genres.Any(x => x.Id == g.Id) }) + .ToList(); + + viewModel.Tags = TagService.Get() + .OrderBy(t => t.Name) + .Select(t => new SelectListItem() { Text = t.Name, Value = t.Name, Selected = viewModel.Game.Tags.Any(x => x.Id == t.Id) }) + .ToList(); + + return View(viewModel); } // POST: Games/Edit/5 @@ -320,34 +302,91 @@ namespace LANCommander.Controllers // For more details, see http://go.microsoft.com/fwlink/?LinkId=317598. [HttpPost] [ValidateAntiForgeryToken] - public async Task Edit(Guid id, Game game) + public async Task Edit(Guid id, GameViewModel viewModel) { - if (id != game.Id) + if (id != viewModel.Game.Id) { return NotFound(); } if (ModelState.IsValid) { - try + var game = await GameService.Get(viewModel.Game.Id); + + game.Title = viewModel.Game.Title; + game.Description = viewModel.Game.Description; + game.ReleasedOn = viewModel.Game.ReleasedOn; + + #region Update Developers + foreach (var developer in game.Developers) { - await GameService.Update(game); + if (!viewModel.SelectedDevelopers.Any(d => d == developer.Name)) + game.Developers.Remove(developer); } - catch (DbUpdateConcurrencyException) + + foreach (var newDeveloper in viewModel.SelectedDevelopers.Where(sd => !game.Developers.Any(d => d.Name == sd))) { - if (!GameService.Exists(game.Id)) + game.Developers.Add(new Company() { - return NotFound(); - } - else - { - throw; - } + Name = newDeveloper + }); } + #endregion + + #region Update Publishers + foreach (var publisher in game.Publishers) + { + if (!viewModel.SelectedPublishers.Any(p => p == publisher.Name)) + game.Publishers.Remove(publisher); + } + + foreach (var newPublisher in viewModel.SelectedPublishers.Where(sp => !game.Publishers.Any(p => p.Name == sp))) + { + game.Publishers.Add(new Company() + { + Name = newPublisher + }); + } + #endregion + + #region Update Genres + foreach (var genre in game.Genres) + { + if (!viewModel.SelectedGenres.Any(g => g == genre.Name)) + game.Genres.Remove(genre); + } + + foreach (var newGenre in viewModel.SelectedGenres.Where(sg => !game.Genres.Any(g => g.Name == sg))) + { + game.Genres.Add(new Genre() + { + Name = newGenre + }); + } + #endregion + + #region Update Tags + foreach (var tag in game.Tags) + { + if (!viewModel.SelectedTags.Any(t => t == tag.Name)) + game.Tags.Remove(tag); + } + + foreach (var newTag in viewModel.SelectedTags.Where(st => !game.Tags.Any(t => t.Name == st))) + { + game.Tags.Add(new Tag() + { + Name = newTag + }); + } + #endregion + + await GameService.Update(game); return RedirectToAction(nameof(Index)); } - return View(game); + + return View(viewModel); } // GET: Games/Delete/5 diff --git a/LANCommander/Services/BaseDatabaseService.cs b/LANCommander/Services/BaseDatabaseService.cs index 324b391..fccb3c4 100644 --- a/LANCommander/Services/BaseDatabaseService.cs +++ b/LANCommander/Services/BaseDatabaseService.cs @@ -82,6 +82,8 @@ namespace LANCommander.Services { using (var repo = new Repository(Context, HttpContext)) { + Context.Attach(entity); + entity = repo.Update(entity); await repo.SaveChanges(); diff --git a/LANCommander/Views/Games/Edit.cshtml b/LANCommander/Views/Games/Edit.cshtml index 0c979b9..1ad428a 100644 --- a/LANCommander/Views/Games/Edit.cshtml +++ b/LANCommander/Views/Games/Edit.cshtml @@ -1,5 +1,5 @@ @using LANCommander.Data.Models -@model LANCommander.Data.Models.Game +@model LANCommander.Models.GameViewModel @{ ViewData["Title"] = "Edit"; @@ -29,27 +29,52 @@
- - - + +
+ + +
+
- - - + + +
- - - + + +
- - - + + + +
+
+ + + +
+
+ + +
- +
+ + + +
+ +
+ + + +
+ + @@ -65,18 +90,18 @@
- @if (Model.Keys != null && Model.Keys.Count > 0) + @if (Model.Game.Keys != null && Model.Game.Keys.Count > 0) { - var keysAvailable = Model.Keys.Count(k => + var keysAvailable = Model.Game.Keys.Count(k => { return (k.AllocationMethod == KeyAllocationMethod.MacAddress && String.IsNullOrWhiteSpace(k.ClaimedByMacAddress)) || (k.AllocationMethod == KeyAllocationMethod.UserAccount && k.ClaimedByUser == null); @@ -93,13 +118,13 @@
Claimed
- @(Model.Keys.Count - keysAvailable) + @(Model.Game.Keys.Count - keysAvailable)
Total
- @Model.Keys.Count + @Model.Game.Keys.Count
@@ -111,7 +136,7 @@

No Keys

There have been no keys added for this game.

} @@ -120,12 +145,12 @@
- @if (Model.Archives != null && Model.Archives.Count > 0) + @if (Model.Game.Archives != null && Model.Game.Archives.Count > 0) {

Archives

- + Add @@ -145,7 +170,7 @@ - @foreach (var archive in Model.Archives.OrderByDescending(a => a.CreatedOn)) + @foreach (var archive in Model.Game.Archives.OrderByDescending(a => a.CreatedOn)) { @Html.DisplayFor(m => archive.Version) @@ -170,7 +195,7 @@

No Archives

There have been no archives uploaded for this game.

} @@ -182,4 +207,61 @@ @section Scripts { @{ await Html.RenderPartialAsync("_ValidationScriptsPartial"); } + + }