I was success to get data from external API in rails,
# products_controller.rb
def load_detail_product
@response = HTTParty.get("http://localhost:3000/api/v1/products/#{params[:id]}",:headers =>{'Content-Type' => 'application/json'})
@detail_products = @response.parsed_response
@product = @detail_products['data']['product']
@product.each do |p|
@product_id = p['id']
end
end
In view, when I want create update form I just do like this
<%= link_to 'Edit', edit_product_path(@product_id) %>
but when I call it to _form.html.erb Im geing this error
undefined method `model_name' for #<Hash:0x00007ffb71715cb8>
# _form.html.erb
<%= form_for @product, authenticity_token: false do |form| %>
<div class="field">
<%= f.label :name %>
<%= f.text_field :name %>
</div>
<div class="actions">
<%= f.submit %>
</div>
<% end %>
how I get data from external API and put it on form_for and update the data?
my response API
# localhost:3000/api/v1/products/1
{
"messages": "Product Loaded Successfully",
"is_success": true,
"data": {
"product": [
{
"id": 1,
"name": "Chair",
"price": "200000",
"created_at": "2022-03-22T09:24:40.796Z",
"updated_at": "2022-03-22T09:24:40.796Z"
}
]
}
}
# for update PUT localhost:3000/api/v1/products/1
{
"product":
{
"name":"Chair",
"price":20000
}
}
The main problem here is that you're not creating an abstraction layer between your application and the outside collaborator. By performing a HTTP query directly from your controller and passing the results straight to the view you're making a strong coupling between your application and the API and any changes to the collaborator can break large portions of your application. This creates a fat controller and pushes all the complexity of dealing with the API responses down into the view which both are very bad things.
I would start by actually creating a model that represents a the data in your application:
Note that it doesn't inherit from ApplicationRecord - this is a model thats not backed by a database table and instead just uses the API's that rails provide to make it quack like a model - this means it will work right out the box with forms:
The
persisted?method tells the helpers that we updating a model and that it should route toproduct_path(id)and use PATCH.But you also need to move the HTTP call out of the controller into a separate class:
This isn't necissarily the only way or even the right way to write this class. The main point is just that you should not be burdoning your controller with more responsibilies. It has tons of jobs already.
This http client is the only component that should be touching the application boundy and have knowledge of the API. It can be tested in isolation and stubbed out when needed.
Your controller then "talks" to the API only though this client: