Make Farm CRUD

This commit is contained in:
Артем Харламов 2024-10-29 00:40:58 +04:00
parent 33c3a074da
commit c4899d4a11
6 changed files with 306 additions and 0 deletions

View File

@ -0,0 +1,128 @@
using Cloud.Models;
using Cloud.Requests;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
namespace Cloud.Controllers
{
[Authorize]
[ApiController]
[Route("api/user")]
public class FarmController : ControllerBase
{
private IConfiguration _config;
private ApplicationContext _context;
public FarmController(IConfiguration config, ApplicationContext context)
{
_config = config;
_context = context;
}
[HttpGet("{userId}/farm")]
public async Task<ActionResult<List<Farm>>> Index (int userId)
{
try
{
List<Farm> farms = await
_context.Farms.Where(x => x.UserId == userId).AsNoTracking().ToListAsync();
if (!farms.Any())
return NotFound("Farms is not found");
return Ok(farms);
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
[HttpGet("{userId}/farm/{farmId}")]
public async Task<ActionResult<Farm>> Show(int userId, int farmId)
{
try
{
Farm? farm = await
_context.Farms.FirstOrDefaultAsync(x => x.UserId == userId && x.Id == farmId);
if (farm == null)
return NotFound("Farm is not found");
return Ok(farm);
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
[HttpPost("{userId}/farm")]
public async Task<ActionResult<Farm>> Create([FromBody] FarmRequest farmRequest, int userId)
{
try
{
var farm = new Farm {
Name = farmRequest.Name,
UserId = userId,
RaspberryMacAddr = farmRequest.RaspberryMacAddr,
};
Farm? farmCreated = _context.Farms.Add(farm).Entity;
await _context.SaveChangesAsync();
return Ok(farmCreated);
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
[HttpPut("{userId}/farm/{farmId}")]
public async Task<ActionResult<Farm>> Update([FromBody] FarmRequest farmRequest, int userId, int farmId)
{
try
{
Farm? farm = await _context.Farms.FirstOrDefaultAsync(x => x.Id == farmId && x.UserId == userId);
if (farm == null)
return NotFound("Farm is not found");
farm.Name = farmRequest.Name;
farm.RaspberryMacAddr = farmRequest.RaspberryMacAddr;
_context.Farms.Update(farm);
await _context.SaveChangesAsync();
return Ok(farm);
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
[HttpDelete("{userId}/farm/{farmId}")]
public async Task<ActionResult> Delete(int userId, int farmId)
{
try
{
Farm? farm = await _context.Farms.FirstOrDefaultAsync(x => x.Id == farmId && x.UserId == userId);
if (farm == null)
return NotFound("Farm is not found");
_context.Farms.Remove(farm);
await _context.SaveChangesAsync();
return Ok("Farm deleted successfully");
}
catch (Exception ex)
{
return BadRequest(ex.Message);
}
}
}
}

View File

@ -0,0 +1,95 @@
// <auto-generated />
using Cloud;
using Microsoft.EntityFrameworkCore;
using Microsoft.EntityFrameworkCore.Infrastructure;
using Microsoft.EntityFrameworkCore.Migrations;
using Microsoft.EntityFrameworkCore.Storage.ValueConversion;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace Cloud.Migrations
{
[DbContext(typeof(ApplicationContext))]
[Migration("20241028192806_CreateFarmsTable")]
partial class CreateFarmsTable
{
protected override void BuildTargetModel(ModelBuilder modelBuilder)
{
#pragma warning disable 612, 618
modelBuilder
.HasAnnotation("ProductVersion", "6.0.14")
.HasAnnotation("Relational:MaxIdentifierLength", 63);
NpgsqlModelBuilderExtensions.UseIdentityByDefaultColumns(modelBuilder);
modelBuilder.Entity("Cloud.Models.Farm", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("RaspberryMacAddr")
.IsRequired()
.HasColumnType("text");
b.Property<int>("UserId")
.HasColumnType("integer");
b.HasKey("Id");
b.HasIndex("UserId");
b.ToTable("Farms");
});
modelBuilder.Entity("Cloud.Models.User", b =>
{
b.Property<int>("Id")
.ValueGeneratedOnAdd()
.HasColumnType("integer");
NpgsqlPropertyBuilderExtensions.UseIdentityByDefaultColumn(b.Property<int>("Id"));
b.Property<string>("Email")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Name")
.IsRequired()
.HasColumnType("text");
b.Property<string>("Password")
.IsRequired()
.HasColumnType("text");
b.HasKey("Id");
b.ToTable("Users");
});
modelBuilder.Entity("Cloud.Models.Farm", b =>
{
b.HasOne("Cloud.Models.User", "User")
.WithMany("Farms")
.HasForeignKey("UserId")
.OnDelete(DeleteBehavior.Cascade)
.IsRequired();
b.Navigation("User");
});
modelBuilder.Entity("Cloud.Models.User", b =>
{
b.Navigation("Farms");
});
#pragma warning restore 612, 618
}
}
}

View File

@ -0,0 +1,45 @@
using Microsoft.EntityFrameworkCore.Migrations;
using Npgsql.EntityFrameworkCore.PostgreSQL.Metadata;
#nullable disable
namespace Cloud.Migrations
{
public partial class CreateFarmsTable : Migration
{
protected override void Up(MigrationBuilder migrationBuilder)
{
migrationBuilder.CreateTable(
name: "Farms",
columns: table => new
{
Id = table.Column<int>(type: "integer", nullable: false)
.Annotation("Npgsql:ValueGenerationStrategy", NpgsqlValueGenerationStrategy.IdentityByDefaultColumn),
Name = table.Column<string>(type: "text", nullable: false),
UserId = table.Column<int>(type: "integer", nullable: false),
RaspberryMacAddr = table.Column<string>(type: "text", nullable: false)
},
constraints: table =>
{
table.PrimaryKey("PK_Farms", x => x.Id);
table.ForeignKey(
name: "FK_Farms_Users_UserId",
column: x => x.UserId,
principalTable: "Users",
principalColumn: "Id",
onDelete: ReferentialAction.Cascade);
});
migrationBuilder.CreateIndex(
name: "IX_Farms_UserId",
table: "Farms",
column: "UserId");
}
protected override void Down(MigrationBuilder migrationBuilder)
{
migrationBuilder.DropTable(
name: "Farms");
}
}
}

12
Cloud/Models/Farm.cs Normal file
View File

@ -0,0 +1,12 @@
namespace Cloud.Models
{
public class Farm
{
public int Id { get; set; }
public string Name { get; set; }
public int UserId { get; set; }
public User? User { get; set; }
public string RaspberryMacAddr { get; set; }
}
}

View File

@ -0,0 +1,8 @@
namespace Cloud.Requests
{
public class FarmRequest
{
public string Name { get; set; }
public string RaspberryMacAddr { get; set; }
}
}

View File

@ -0,0 +1,18 @@
using Cloud.Requests;
using FluentValidation;
namespace Cloud.Validation
{
public class FarmValidator : AbstractValidator<FarmRequest>
{
public FarmValidator()
{
RuleFor(request => request.RaspberryMacAddr)
.NotEmpty().WithMessage("MAC address can't be empty")
.Matches("^([0-9A-Fa-f]{2}[:-]?){5}([0-9A-Fa-f]{2})$").WithMessage("MAC address is not valid");
RuleFor(request => request.Name)
.NotEmpty().WithMessage("Name can't be empty");
}
}
}