【Rails】입력된 값을 바탕으로 GET요청을 보내 데이터를 취득하여 DB에 저장
하는 것
이번에는 GET statuses/oembed — Twitter Developers을 사용하여 트위터 카드를 표시합니다.
임베디드 HTML을 검색하려면 인증이 필요하지 않으므로 간단한 요청으로 데이터를 검색할 수 있습니다.
흐름은 다음과 같습니다.
개발 환경
Ruby 2.6.5
Rails 5.2.3
MySQL 8.0.19
컨트롤러
별도로 드문 일은하지 않습니다.
redirect_to, render는 적합합니다.
tweets_controller.rb
class TweetsController < ApplicationController
def create
if @tweet.create(tweet_params)
redirect_to tweet_path(@tweet)
else
render :new
end
end
def update
@tweet = Tweet.find(params[:id])
if @tweet.update(tweet_params)
redirect_to tweet_path(@tweet)
else
render :edit
end
end
private
def tweet_params
params.require(:tweet).permit(:url)
end
end
모델
사전에 json을 넣을 예정인
t_json
컬럼을 마이그레이션으로 작성해 둡니다.(추기) json을 1 컬럼을 넣는 것은, 변경이나 데이터의 취득이 곤란하기 때문에 안티 패턴이라고 말해지고 있습니다. 사용할 때는주의하십시오.
tweet.rb
# == Schema Information
#
# Table name: tweets
#
# id :bigint not null, primary key
# url :string(255) not null
# t_json :json not null
# created_at :datetime not null
# updated_at :datetime not null
#
class Tweet < ApplicationRecord
validates :url, presence: true, length: { maximum: 200 }
end
이 상태에서는 입력한 URL만 저장됩니다. 그래서 url에서 t_json을 얻고 저장할 때까지의 흐름을 순서대로 따라갑니다.
1. 입력된 URL에서 ID 얻기
URL은, 예를 들면
https://twitter.com/Interior/status/507185938620219395
의 형태가 됩니다만, 요구에 필요한 것은 ID의 507185938620219395
의 부분만입니다.그러면 입력된 URL에서 ID가 되는 문자열을 추출하는
tweet_id
라는 인스턴스 메서드를 만듭니다. def tweet_id
url.split('/').last
end
덧붙여서,
tweet.tweet_id
라고 하는 쓰는 방법으로, 모델의 외부로부터도 ID를 취득할 수 있습니다.2. 요청을 제출하여 데이터 검색
TwitterAPI에 GET 요청을 보냅니다.
curl 명령은 다음과 같은 명령입니다.
ExampleRequest
$ curl 'https://publish.twitter.com/oembed?url=https%3A%2F%2Ftwitter.com%2FInterior%2Fstatus%2F507185938620219395'
이것을 Ruby로 구현합니다. 두 가지 방법을 언급합니다.
open_uri를 사용하는 방법
def tweet_json
url = "https://publish.twitter.com/oembed?url=https%3A%2F%2Ftwitter.com%2FInterior%2Fstatus%2F#{tweet_id}"
responce = OpenURI.open_uri(url) # リクエストを送り、返り値をresponceに代入
ActiveSupport::JSON.decode(responce.read)
end
Net :: HTTP를 사용하는 방법
def tweet_json
url = "https://publish.twitter.com/oembed?url=https%3A%2F%2Ftwitter.com%2FInterior%2Fstatus%2F#{tweet_id}"
uri = URI.parse(url)
responce = Net::HTTP.get(uri) # リクエストを送り、返り値をresponceに代入
JSON.parse(responce)
end
Ruby HTTP 요청을 보내는 방법의 성능 비교 에 의하면, Net::HTTP 쪽이 빠른 것 같습니다.
이제 다음과 같은 json 형식의 데이터를 반환하는 메서드를 만들 수있었습니다.
{
"url": "https://twitter.com/Interior/status/507185938620219395",
"author_name": "US Dept of Interior",
"author_url": "https://twitter.com/Interior",
"html": "<blockquote class="twitter-tweet"><p lang="en" dir="ltr">Happy 50th anniversary to the Wilderness Act! Here's a great wilderness photo from <a href="https://twitter.com/YosemiteNPS">@YosemiteNPS</a>. <a href="https://twitter.com/hashtag/Wilderness50?src=hash">#Wilderness50</a> <a href="http://t.co/HMhbyTg18X">pic.twitter.com/HMhbyTg18X</a></p>— US Dept of Interior (@Interior) <a href="https://twitter.com/Interior/status/507185938620219395">September 3, 2014</a></blockquote>n<script async src="//platform.twitter.com/widgets.js" charset="utf-8"></script>",
"width": 550,
"height": null,
"type": "rich",
"cache_age": "3153600000",
"provider_name": "Twitter",
"provider_url": "https://twitter.com",
"version": "1.0"
}
3. 얻은 json을 tweet.t_json에 저장하고 저장
tweet을 저장하기 전에
before_save
를 사용하여 t_json
에 값을 넣기로 합니다.set_json
메소드의 역할은, URL이 변경되고 있었을 경우, t_json
에 값을 넣는다는 것입니다.외부 API를 너무 두드리는 것은 좋지 않기 때문에 URL이 바뀌지 않은 경우는 특별히 변경하지 않습니다 (이번 예에서는 그 밖에 변경할 수 있는 컬럼이 없기 때문에 별로 필요하지 않습니다만).
tweet.rb
class Tweet < ApplicationRecord
before_save :set_json # 追加
def set_json
self.t_json = tweet_json if will_save_change_to_url?
end
def tweet_json
# TwitterAPIから取得したJSONデータを返す
end
end
최종 모델
tweet.rb
class Tweet < ApplicationRecord
before_save :set_json
validates :url, presence: true, length: { maximum: 200 }
def tweet_id
url.split('/').last
end
private # 以下のメソッドは外部から呼び出さないのでprivateにする
def set_json
self.t_json = tweet_json if will_save_change_to_url?
end
def tweet_json
url = "https://publish.twitter.com/oembed?url=https%3A%2F%2Ftwitter.com%2FInterior%2Fstatus%2F#{tweet_id}"
uri = URI.parse(url)
responce = Net::HTTP.get(uri)
JSON.parse(responce)
end
보기
Twitter 카드를 표시하려면 json의
"html"
를 그대로 HTML로 출력하면 좋으므로 뷰 파일에서 다음과 같이 작성합니다.view.html.erb
<%= @tweet.t_json['html'].html_safe %>
트윗 정보를 얻는 옵션
"https://publish.twitter.com/oembed?url=https%3A%2F%2Ftwitter.com%2FInterior%2Fstatus%2F#{tweet_id}&omit_script=true"
이렇게
&
로 연결합니다. (파라미터의 종류에 대해서는 공식 페이지 참조)omit_script=true
로 하면, <script>
부분을 제외한 HTML이 돌려주어지므로, 1 페이지에 복수의 트윗을 표시하는 경우는 추천입니다.view.html.erb
<% @tweets.each do |tweet| %>
<%= tweet.t_json['html'].html_safe %>
<% end %>
<%= javascript_include_tag '//platform.twitter.com/widgets.js' %>
링크
예외 처리 등 세세하게 실시하는 경우
Reference
이 문제에 관하여(【Rails】입력된 값을 바탕으로 GET요청을 보내 데이터를 취득하여 DB에 저장), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://qiita.com/aiandrox/items/ba82db7c12d413cb4cef텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)