diff --git a/Controllers/QuoteController.cs b/Controllers/QuoteController.cs index a00efce..38221a1 100644 --- a/Controllers/QuoteController.cs +++ b/Controllers/QuoteController.cs @@ -2,6 +2,7 @@ using Microsoft.AspNetCore.Mvc; using Microsoft.AspNetCore.Authorization; using QuotifyBE.Data; using QuotifyBE.Entities; +using QuotifyBE.Mapping; using System.Security.Claims; using Microsoft.EntityFrameworkCore; @@ -40,7 +41,7 @@ public class QuotesController : ControllerBase .Include(q => q.QuoteCategories!) .ThenInclude(qc => qc.Category) .Include(q => q.User) - .Include(q => q.ImageId) + .Include(q => q.Image) .FirstOrDefaultAsync(q => q.Id == id); if (quote == null) @@ -48,7 +49,7 @@ public class QuotesController : ControllerBase // TODO: Consider turning the quote into a DTO - return Ok(quote); + return Ok(quote.ToQuoteShortDTO(_db)); } // POST /api/v1/quotes/new @@ -135,7 +136,7 @@ public class QuotesController : ControllerBase image = await _db.Images.FirstOrDefaultAsync(i => i.Id == quote.ImageId); } - var dto = new RandomQuote + var dto = new QuoteShortDTO { Text = quote.Text, Author = quote.Author, diff --git a/DTOs/RandomQuoteDTO.cs b/DTOs/QuoteShortDTO.cs similarity index 76% rename from DTOs/RandomQuoteDTO.cs rename to DTOs/QuoteShortDTO.cs index e593e6b..6f57d05 100644 --- a/DTOs/RandomQuoteDTO.cs +++ b/DTOs/QuoteShortDTO.cs @@ -1,5 +1,6 @@ -public record class RandomQuote +public record class QuoteShortDTO { + public int Id { get; set; } public string Text { get; set; } = string.Empty; public string Author { get; set; } = string.Empty; public string? ImageUrl { get; set; } diff --git a/Entities/Quote.cs b/Entities/Quote.cs index 81a37b2..423d79c 100644 --- a/Entities/Quote.cs +++ b/Entities/Quote.cs @@ -8,12 +8,13 @@ namespace QuotifyBE.Entities required public string Text { get; set; } required public string Author { get; set; } //public int CategoryId { get; set; } - public int ImageId { get; set; } + public int? ImageId { get; set; } public DateTime CreatedAt { get; set; } public DateTime LastUpdatedAt { get; set; } public int UserId { get; set; } public User? User { get; set; } - public ICollection? QuoteCategories = new List(); + public Image? Image { get; set; } + public ICollection QuoteCategories { get; set; } = new List(); } } diff --git a/Entities/QuoteCategory.cs b/Entities/QuoteCategory.cs index b5b30a7..06cd14a 100644 --- a/Entities/QuoteCategory.cs +++ b/Entities/QuoteCategory.cs @@ -1,4 +1,4 @@ -namespace QuotifyBE.Entities +namespace QuotifyBE.Entities { public class QuoteCategory { diff --git a/Mapping/QuoteMapping.cs b/Mapping/QuoteMapping.cs new file mode 100644 index 0000000..0887ef1 --- /dev/null +++ b/Mapping/QuoteMapping.cs @@ -0,0 +1,32 @@ +using Microsoft.Extensions.Logging; +using QuotifyBE.Data; +using QuotifyBE.DTOs; +using QuotifyBE.Entities; + +namespace QuotifyBE.Mapping; + +public static class QuoteMapping +{ + + public static QuoteShortDTO ToQuoteShortDTO(this Quote quote, ApplicationDbContext db) + { + + List categoryNames = []; + if (quote.QuoteCategories != null) + { + foreach (QuoteCategory quoteCategory in quote.QuoteCategories) + { + categoryNames.Add(quoteCategory.Category!.Name ?? $"Unnamed category {quoteCategory.CategoryId}"); + } + } + + return new QuoteShortDTO + { + Id = quote.Id, + Text = quote.Text, + Author = quote.Author, + ImageUrl = quote.Image?.Url, + Categories = categoryNames + }; + } +} diff --git a/Migrations/20250714093636_initial_migration.Designer.cs b/Migrations/20250715142242_revised_model.Designer.cs similarity index 90% rename from Migrations/20250714093636_initial_migration.Designer.cs rename to Migrations/20250715142242_revised_model.Designer.cs index c96b12b..b48e5fb 100644 --- a/Migrations/20250714093636_initial_migration.Designer.cs +++ b/Migrations/20250715142242_revised_model.Designer.cs @@ -12,8 +12,8 @@ using QuotifyBE.Data; namespace QuotifyBE.Migrations { [DbContext(typeof(ApplicationDbContext))] - [Migration("20250714093636_initial_migration")] - partial class initial_migration + [Migration("20250715142242_revised_model")] + partial class revised_model { /// protected override void BuildTargetModel(ModelBuilder modelBuilder) @@ -72,7 +72,7 @@ namespace QuotifyBE.Migrations b.Property("CreatedAt") .HasColumnType("timestamp with time zone"); - b.Property("ImageId") + b.Property("ImageId") .HasColumnType("integer"); b.Property("LastUpdatedAt") @@ -87,6 +87,8 @@ namespace QuotifyBE.Migrations b.HasKey("Id"); + b.HasIndex("ImageId"); + b.HasIndex("UserId"); b.ToTable("Quotes"); @@ -104,7 +106,7 @@ namespace QuotifyBE.Migrations b.HasIndex("CategoryId"); - b.ToTable("QuoteCategory"); + b.ToTable("QuoteCategories"); }); modelBuilder.Entity("QuotifyBE.Entities.User", b => @@ -134,12 +136,18 @@ namespace QuotifyBE.Migrations modelBuilder.Entity("QuotifyBE.Entities.Quote", b => { + b.HasOne("QuotifyBE.Entities.Image", "Image") + .WithMany() + .HasForeignKey("ImageId"); + b.HasOne("QuotifyBE.Entities.User", "User") .WithMany() .HasForeignKey("UserId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); + b.Navigation("Image"); + b.Navigation("User"); }); @@ -152,7 +160,7 @@ namespace QuotifyBE.Migrations .IsRequired(); b.HasOne("QuotifyBE.Entities.Quote", "Quote") - .WithMany() + .WithMany("QuoteCategories") .HasForeignKey("QuoteId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); @@ -161,6 +169,11 @@ namespace QuotifyBE.Migrations b.Navigation("Quote"); }); + + modelBuilder.Entity("QuotifyBE.Entities.Quote", b => + { + b.Navigation("QuoteCategories"); + }); #pragma warning restore 612, 618 } } diff --git a/Migrations/20250714093636_initial_migration.cs b/Migrations/20250715142242_revised_model.cs similarity index 85% rename from Migrations/20250714093636_initial_migration.cs rename to Migrations/20250715142242_revised_model.cs index 8806415..8a85a1b 100644 --- a/Migrations/20250714093636_initial_migration.cs +++ b/Migrations/20250715142242_revised_model.cs @@ -7,7 +7,7 @@ using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata; namespace QuotifyBE.Migrations { /// - public partial class initial_migration : Migration + public partial class revised_model : Migration { /// protected override void Up(MigrationBuilder migrationBuilder) @@ -61,7 +61,7 @@ namespace QuotifyBE.Migrations .Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn), Text = table.Column(type: "text", nullable: false), Author = table.Column(type: "text", nullable: false), - ImageId = table.Column(type: "integer", nullable: false), + ImageId = table.Column(type: "integer", nullable: true), CreatedAt = table.Column(type: "timestamp with time zone", nullable: false), LastUpdatedAt = table.Column(type: "timestamp with time zone", nullable: false), UserId = table.Column(type: "integer", nullable: false) @@ -69,6 +69,11 @@ namespace QuotifyBE.Migrations constraints: table => { table.PrimaryKey("PK_Quotes", x => x.Id); + table.ForeignKey( + name: "FK_Quotes_Images_ImageId", + column: x => x.ImageId, + principalTable: "Images", + principalColumn: "Id"); table.ForeignKey( name: "FK_Quotes_Users_UserId", column: x => x.UserId, @@ -78,7 +83,7 @@ namespace QuotifyBE.Migrations }); migrationBuilder.CreateTable( - name: "QuoteCategory", + name: "QuoteCategories", columns: table => new { QuoteId = table.Column(type: "integer", nullable: false), @@ -86,15 +91,15 @@ namespace QuotifyBE.Migrations }, constraints: table => { - table.PrimaryKey("PK_QuoteCategory", x => new { x.QuoteId, x.CategoryId }); + table.PrimaryKey("PK_QuoteCategories", x => new { x.QuoteId, x.CategoryId }); table.ForeignKey( - name: "FK_QuoteCategory_Categories_CategoryId", + name: "FK_QuoteCategories_Categories_CategoryId", column: x => x.CategoryId, principalTable: "Categories", principalColumn: "Id", onDelete: ReferentialAction.Cascade); table.ForeignKey( - name: "FK_QuoteCategory_Quotes_QuoteId", + name: "FK_QuoteCategories_Quotes_QuoteId", column: x => x.QuoteId, principalTable: "Quotes", principalColumn: "Id", @@ -102,10 +107,15 @@ namespace QuotifyBE.Migrations }); migrationBuilder.CreateIndex( - name: "IX_QuoteCategory_CategoryId", - table: "QuoteCategory", + name: "IX_QuoteCategories_CategoryId", + table: "QuoteCategories", column: "CategoryId"); + migrationBuilder.CreateIndex( + name: "IX_Quotes_ImageId", + table: "Quotes", + column: "ImageId"); + migrationBuilder.CreateIndex( name: "IX_Quotes_UserId", table: "Quotes", @@ -116,10 +126,7 @@ namespace QuotifyBE.Migrations protected override void Down(MigrationBuilder migrationBuilder) { migrationBuilder.DropTable( - name: "Images"); - - migrationBuilder.DropTable( - name: "QuoteCategory"); + name: "QuoteCategories"); migrationBuilder.DropTable( name: "Categories"); @@ -127,6 +134,9 @@ namespace QuotifyBE.Migrations migrationBuilder.DropTable( name: "Quotes"); + migrationBuilder.DropTable( + name: "Images"); + migrationBuilder.DropTable( name: "Users"); } diff --git a/Migrations/ApplicationDbContextModelSnapshot.cs b/Migrations/ApplicationDbContextModelSnapshot.cs index 2af654c..0876095 100644 --- a/Migrations/ApplicationDbContextModelSnapshot.cs +++ b/Migrations/ApplicationDbContextModelSnapshot.cs @@ -69,7 +69,7 @@ namespace QuotifyBE.Migrations b.Property("CreatedAt") .HasColumnType("timestamp with time zone"); - b.Property("ImageId") + b.Property("ImageId") .HasColumnType("integer"); b.Property("LastUpdatedAt") @@ -84,6 +84,8 @@ namespace QuotifyBE.Migrations b.HasKey("Id"); + b.HasIndex("ImageId"); + b.HasIndex("UserId"); b.ToTable("Quotes"); @@ -101,7 +103,7 @@ namespace QuotifyBE.Migrations b.HasIndex("CategoryId"); - b.ToTable("QuoteCategory"); + b.ToTable("QuoteCategories"); }); modelBuilder.Entity("QuotifyBE.Entities.User", b => @@ -131,12 +133,18 @@ namespace QuotifyBE.Migrations modelBuilder.Entity("QuotifyBE.Entities.Quote", b => { + b.HasOne("QuotifyBE.Entities.Image", "Image") + .WithMany() + .HasForeignKey("ImageId"); + b.HasOne("QuotifyBE.Entities.User", "User") .WithMany() .HasForeignKey("UserId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); + b.Navigation("Image"); + b.Navigation("User"); }); @@ -149,7 +157,7 @@ namespace QuotifyBE.Migrations .IsRequired(); b.HasOne("QuotifyBE.Entities.Quote", "Quote") - .WithMany() + .WithMany("QuoteCategories") .HasForeignKey("QuoteId") .OnDelete(DeleteBehavior.Cascade) .IsRequired(); @@ -158,6 +166,11 @@ namespace QuotifyBE.Migrations b.Navigation("Quote"); }); + + modelBuilder.Entity("QuotifyBE.Entities.Quote", b => + { + b.Navigation("QuoteCategories"); + }); #pragma warning restore 612, 618 } } diff --git a/QuotifyBE.csproj b/QuotifyBE.csproj index 00432b3..c2e9c3d 100644 --- a/QuotifyBE.csproj +++ b/QuotifyBE.csproj @@ -28,8 +28,4 @@ - - - -