自分で書いた記事に、参考にした記事のタイトルやURLをスクレイピングして持ってきたい。
初めまして、rails初学者です。
現在ポートフォリオ作成の一環として、次のようなWebアプリを作成しています。
自分が気になった記事やニュースなどについて、自分の考えを記事にして投稿できる! 引用を書くのがめんどくさくても大丈夫、参考サイトのURLを入力すると自動でタイトルとURLを引用元として追加してくれます。
これまで実装した範囲で
- スクレイピングしたタイトルとURL、アイキャッチ画像をDBに保存できる
- 作成した記事をDBに保存できる
までは達成したのですが、作成した記事とスクレイピングしたデータとの紐付け方がわかりません。
##試みたこと
railsは複合主キーに対応していないとのことで、多対多のモデルとみなして中間テーブルを作成しました。
記事の内容、スクレイピングした内容はそれぞれのDBに入ってくれるのですが、中間テーブルに値が入ってくれません。
###理想のモデル
(articlesテーブル)→ユーザーが書く記事の内容を保存する
|id|title|text|user_id|
|:--|:--:|--:|
|1|食糧危機について|近年〜|1|
|2|日本経済の行方|少子高齢化が〜|2|
(article_scrapesテーブル)→articlesテーブルとscrapesテーブルの中間テーブル
id | article_id | scrape_id |
---|---|---|
1 | 1 | 1 |
2 | 1 | 2 |
3 | 2 | 3 |
(scrapesテーブル)→URL入力フォームに入力されたURLをスクレイピンしたデータを保存する
|id|url|title|image_url|user_id|
|:--|:--:|--:|
|1|https://〜|アフリカの食糧危機深刻化。|https://〜|1|
|2|https://〜|アフリカを巡る世界情勢。|https://〜|1|
|3|https://〜|日経平均株価の10年を振り返る|https://〜|1
##書いたコード
【Model】
ruby:app>model>article.rb
1class Article < ApplicationRecord 2 belongs_to :user 3 has_many :comments 4 5 has_many :article_scrapes 6 has_many :scrapes, through: :article_scrapes 7end
ruby:app>model>article_scrape.rb
1class ArticleScrape < ApplicationRecord 2 belongs_to :article 3 belongs_to :scrape 4end 5
ruby:app>model>scrape.rb
1class Scrape < ApplicationRecord 2 has_many :article_scrapes 3 has_many :articles, through: :article_scrapes 4end
【コントローラー】
ruby:app>controllers>articles_controller.rb
1class ArticlesController < ApplicationController 2 require 'nokogiri' #import宣言 3 require 'open-uri' 4 5 before_action :move_to_index, except: [:index, :show] 6 7 def index 8 @articles = Article.includes(:user).order("created_at DESC") 9 end 10 11 def new 12 end 13 14 def create 15 url = article_params[:url] #scraping対象URL 16 charset = nil 17 html = crawling(url) 18 19 doc = Nokogiri::HTML.parse(html, nil, charset) 20 title = doc.title 21 image_url = doc.css('img').attribute('src').value 22 scrape = insert_scrape(url, title, image_url) 23 article = scrape.articles.build(article_params) 24 end 25 26 def show 27 @article = Article.find(params[:id]) 28 @comments = @article.comments.includes(:user) 29 end 30 31 def destroy 32 article = Article.find(params[:id]) 33 article.destroy if article.user_id == current_user.id 34 end 35 36 def edit 37 @article = Article.find(params[:id]) 38 end 39 40 def update 41 article = Article.find(params[:id]) 42 if article.user_id == current_user.id 43 article.update(article_params) 44 end 45 end 46 47 private 48 49 def article_params 50 params.permit(:url, :title, :text) 51 end 52 53 def move_to_index 54 redirect_to action: :index unless user_signed_in? 55 end 56 57 def insert_scrape(url, title, image_url) 58 scrape = Scrape.new( 59 :url => url, 60 :title => title, 61 :image_url => image_url 62 ) 63 scrape.save! 64 end 65 66 def insert_article(title, text, user_id,random_id) 67 article = Article.new( 68 :title => title, 69 :text => text, 70 :user_id => user_id, 71 :random_id => random_id 72 ) 73 article.save! 74 75 end 76 77 def crawling(url) 78 open(url) do |f| 79 charset = f.charset 80 f.read 81 end 82 end 83end 84
発生している問題・エラーメッセージ
補足情報
- ruby 2.5.1p57
- Rails 5.2.4.1
長々とお読みいただきありがとうございました。
解決策、並びに代替案などございましたら(優しく)回答いただけると嬉しいです。
よろしくお願いいたします。
回答1件
あなたの回答
tips
プレビュー