Hey there, fellow developers! I wanted to share an exciting journey I recently undertook to enhance my MVP app. As the first and only user, I discovered some important bugs and realized that I needed a more flexible approach to manage the data in my application.
One of the primary issues was related to mounting and demounting bike parts using the API. At first, I could only work with the current date, which was quite limiting. I needed the ability to configure my bike, which I’ve had for a while, without manually tinkering with the database. Fortunately, the solution turned out to be surprisingly simple: I needed to introduce new parameters into the component assignments API.
- Updating the Contract To get started, I made changes to the contract, which defines the parameters for the API:
module App
module Contracts
class ComponentAssignment < Dry::Validation::Contract
params do
required(:bike_id).filled(:integer)
required(:component_id).filled(:integer)
optional(:started_at).maybe(:date_time)
optional(:ended_at).maybe(:date_time)
end
end
end
end
The contract now includes the started_at and ended_at fields, which can be used for configuring bike components.
- Updating the Controller Next, I updated the controller to make use of these new parameters when creating a component assignment:
component = Repositories::ComponentAssignments.new.create(
bike_id: component_data["bike_id"],
component_id: component_data["component_id"],
started_at: component_data["started_at"],
ended_at: component_data["ended_at"]
)
This change allowed me to set the started_at and ended_at values directly in the API endpoint, eliminating the need for direct database manipulation.
- Updating the Repository To complete the process, I had to modify the repository to accommodate the new parameters:
module App
module Repositories
class RecordNotFound < StandardError
end
class ComponentAssignments
def create(bike_id:, component_id:, started_at:, ended_at:)
started_at = Time.now if started_at.blank()
Records::ComponentAssignment.create(
bike_id: bike_id,
component_id: component_id,
started_at: started_at,
ended_at: ended_at
)
end
def delete(bike_id:, component_id:, ended_at:)
ended_at = Time now if ended_at.blank?
assignment = Records::ComponentAssignment.find_by!(bike_id:, component_id:, ended_at: nil)
assignment.update(ended_at: ended_at)
rescue ActiveRecord::RecordNotFound
raise RecordNotFound.new
end
end
end
end
Now, the create
method in the repository accepts the started_at
and ended_at
parameters and defaults to the current time when these fields are empty.
By implementing these changes, I transformed my MVP app into a more versatile tool that allows me to work with historical data in addition to the present. I can set started_at
and ended_at
directly in the API endpoint, avoiding direct database interactions on the server.
I hope my experience in improving my app’s API parameters inspires you to enhance your own projects. Code is on github. Stay curious, keep coding, and happy developing!