外部APIに入力フォームの値のリクエストを渡して、DBに保存したい
解決したいこと
入力フォームからの情報をHeartrailsGeoAPI(外部API)へリクエストで送り、最終的に住所をDBに保存したいです。
下記の記事を参考にコードを書き、Postmanで値を検証したのですが、NomethodErrorなどが出ます。
https://qiita.com/4ma9147/items/2d377dedf9237b54ba37
※今回マスターテーブルを作成しており、Officeモデルの外部キーに設定しているMunicipalityカラム(市区町村)と、外部APIのCityカラムの値が一致したら、DBに保存したいという実装を考えています。
発生している問題・エラー
"status": 500,
"error": "Internal Server Error",
"exception": "#<NoMethodError: undefined method `[]' for nil:NilClass\n\n
params = URI.encode_www_form(params[:postal])\n
該当するソースコード
office.rb
require 'json'
require 'net/https'
require 'uri'
class Office < ApplicationRecord
belongs_to :municipality
before_validation :searchByPostal
validates :name, presence: true
validates :postal, presence: true
validates :prefecture, presence: true
validates :city, presence:true
validates :town, presence: true
def searchByPostal
params = URI.encode_www_form(params[:postal])
uri = URI.parse("https://geoapi.heartrails.com/api/json?method=searchByPostal&postal=#{params[:postal]}")
response = Net::HTTP.get_response(uri)
if result = JSON.parse(response.body)
postal = result["results"][0]["postal"]
prefecture = result["results"][0]["prefecture"]
city = result["results"][0]["city"]
town = result["results"][0]["town"]
end
end
end
例)
routes.rb
Rails.application.routes.draw do
namespace 'api' do
namespace 'v1' do
namespace 'clients' do
namespace :admin do
post 'offices', to: 'offices#create'
resources :offices, defaults: { format: :json } do
collection do
post 'searchByPostal'
end
end
end
end
end
end
end
offices_controller.rb
module Api
module V1
module Clients
class Admin::OfficesController < ApplicationController
def create
@office = Office.create(office_params)
municipality_id = Municipality.find_by(name: params[:city])
@office.municipality = municipality_id
if @office.save!
render json: { status: 'SUCCESS', data: @office }
else
render json: { status: 'ERROR', data: @office.errors }
end
end
private
def office_params
params.permit(:name, :address, :name_rep, :title, :feature_detail, :type, :established_date, :rooms, :requirements, :public_facilities, :business_entity, :official_site, :tell, :fax)
end
end
end
end
end
db/migrate/20221016151105_create_offices.rb
class CreateOffices < ActiveRecord::Migration[7.0]
def change
create_table :offices do |t|
t.string :name
t.references :municipality, foreign_key: true
t.timestamps
end
end
end
自分で試したこと
以下の内容でもoffice.rbを書いてみましたが、うまくいきません。
office.rb
require 'json'
require 'net/https'
require 'uri'
class Office < ApplicationRecord
belongs_to :municipality
before_validation :searchByPostal
validates :name, presence: true
validates :postal, presence: true
validates :prefecture, presence: true
validates :city, presence:true
validates :town, presence: true
def searchByPostal
if params[:postal] == "acitivated"
@offices = Office.activated
else
@offices = Office.inactivated
end
params = URI.encode_www_form(params[:postal])
uri = URI.parse("https://geoapi.heartrails.com/api/json?method=searchByPostal&postal=#{params[:postal]}")
https = Net::HTTP.new(url.host, url.port)
https.use_ssl =true
http.verify_mode = OpenSSL::SSL::VERIFY_NONE
req = Net::HTTP.get_response(uri.path)
res = https.request(req)
if result = JSON.parse(response.body)
postal = result["results"][0]["postal"]
prefecture = result["results"][0]["prefecture"]
city = result["results"][0]["city"]
town = result["results"][0]["town"]
end
# end
end
end
0