diff --git a/lib/rent_cars/cars.ex b/lib/rent_cars/cars.ex index da5dde5..30814c2 100644 --- a/lib/rent_cars/cars.ex +++ b/lib/rent_cars/cars.ex @@ -2,9 +2,18 @@ defmodule RentCars.Cars do alias __MODULE__.Car alias RentCars.Repo + def get_car!(id), do: Repo.get!(Car, id) + def create(attrs) do %Car{} |> Car.changeset(attrs) |> Repo.insert() end + + def update(car_id, attrs) do + car_id + |> get_car!() + |> Car.update_changeset(attrs) + |> Repo.update() + end end diff --git a/lib/rent_cars/cars/car.ex b/lib/rent_cars/cars/car.ex index e50836d..dd5a62b 100644 --- a/lib/rent_cars/cars/car.ex +++ b/lib/rent_cars/cars/car.ex @@ -7,20 +7,19 @@ defmodule RentCars.Cars.Car do @primary_key {:id, :binary_id, autogenerate: true} @foreign_key_type :binary_id - @fields ~w/ available brand daily_rate description fine_amount license_plate name category_id/a - + @fields ~w/available brand daily_rate description fine_amount license_plate name category_id/a schema "cars" do - field :name, :string - field :description, :string field :available, :boolean, default: true field :brand, :string field :daily_rate, :integer + field :description, :string field :fine_amount, :integer field :license_plate, :string + field :name, :string belongs_to :category, Category many_to_many :specifications, Specification, join_through: CarSpecification - timestamps(type: :utc_datetime) + timestamps() end @doc false @@ -32,4 +31,16 @@ defmodule RentCars.Cars.Car do |> unique_constraint(:license_plate) |> cast_assoc(:specifications, with: &Specification.changeset/2) end + + def update_changeset(car, attrs) do + car + |> changeset(attrs) + |> validate_change(:license_plate, fn :license_plate, license_plate -> + if car.license_plate != license_plate do + [license_plate: "you can`t update license_plate"] + else + [] + end + end) + end end diff --git a/lib/rent_cars/cars/car_specification.ex b/lib/rent_cars/cars/car_specification.ex index 64df197..fa5cad6 100644 --- a/lib/rent_cars/cars/car_specification.ex +++ b/lib/rent_cars/cars/car_specification.ex @@ -1,22 +1,22 @@ defmodule RentCars.Cars.CarSpecification do - use Ecto.Schema - import Ecto.Changeset - alias RentCars.Cars.Car - alias RentCars.Specifications.Specification + use Ecto.Schema + import Ecto.Changeset + alias RentCars.Cars.Car + alias RentCars.Specifications.Specification - @primary_key {:id, :binary_id, autogenerate: true} - @foreign_key_type :binary_id - schema "cars_specifications" do - belongs_to(:car, Car) - belongs_to(:specification, Specification) + @primary_key {:id, :binary_id, autogenerate: true} + @foreign_key_type :binary_id + schema "cars_specifications" do + belongs_to :car, Car + belongs_to :specification, Specification timestamps(type: :utc_datetime) end - @doc false - def changeset(car_specification, attrs) do - car_specification - |> cast(attrs, []) - |> validate_required([]) - end -end + @doc false + def changeset(car_specification, attrs) do + car_specification + |> cast(attrs, []) + |> validate_required([]) + end + end diff --git a/priv/repo/migrations/20240108111318_create_cars.exs b/priv/repo/migrations/20240108111318_create_cars.exs index 32b1418..282b037 100644 --- a/priv/repo/migrations/20240108111318_create_cars.exs +++ b/priv/repo/migrations/20240108111318_create_cars.exs @@ -23,7 +23,6 @@ defmodule RentCars.Repo.Migrations.CreateCars do end create unique_index(:cars, [:license_plate]) - create index(:cars, [:category_id]) end end diff --git a/test/rent_cars/cars_test.exs b/test/rent_cars/cars_test.exs index 8e6951d..384ba0e 100644 --- a/test/rent_cars/cars_test.exs +++ b/test/rent_cars/cars_test.exs @@ -2,6 +2,7 @@ defmodule RentCars.CarsTest do use RentCars.DataCase alias RentCars.Cars import RentCars.CategoriesFixtures + import RentCars.CarsFixtures test "create car with success" do category = category_fixture() @@ -51,4 +52,18 @@ defmodule RentCars.CarsTest do end ) end + + test "update a car with success" do + car = car_fixture() + payload = %{name: "Lancer 2023"} + assert {:ok, car} = Cars.update(car.id, payload) + assert car.name == payload.name + end + + test "throw error when try updating the licence_plate" do + car = car_fixture() + payload = %{license_plate: "update license_plate"} + assert {:error, changeset} = Cars.update(car.id, payload) + assert "you can`t update license_plate" in errors_on(changeset).license_plate + end end diff --git a/test/support/fixtures/cars_fixtures.ex b/test/support/fixtures/cars_fixtures.ex new file mode 100644 index 0000000..fc833fe --- /dev/null +++ b/test/support/fixtures/cars_fixtures.ex @@ -0,0 +1,48 @@ +defmodule RentCars.CarsFixtures do + alias RentCars.Cars + import RentCars.CategoriesFixtures + + def car_attrs(attrs \\ %{}) do + category = category_fixture() + + valid_attrs = + %{ + name: "Honda City", + description: "Good car", + brand: "Honda", + daily_rate: 100, + license_plate: "adfdf #{:rand.uniform(10_000)}", + fine_amount: 30, + category_id: category.id, + specifications: [ + %{ + name: "wheels", + description: "4 wheels" + }, + %{ + name: "steering", + description: "electric" + }, + %{ + name: "navigation", + description: "navigation included" + }, + %{ + name: "cruze control", + description: "cruze control included" + } + ] + } + + Enum.into(attrs, valid_attrs) + end + + def car_fixture(attrs \\ %{}) do + {:ok, car} = + attrs + |> car_attrs() + |> Cars.create() + + car + end +end