学習メモ

Ruby on Railsを中心にプログラミングやWEB技術を勉強しています。

ogpの情報を取得したい

nokogiriを利用したスクレイピング

アプリ制作に伴いogpの情報を自分のアプリ内で表示したいと思って調べました。
今回はurlを登録するとそのサイトのmetaタグから情報を取得して、データベースに保存するサンプルを作ります。

環境

  • ruby 2.6.6
  • rails 6.0.3
  • nokogiri 1.11.3
  • image_processing 1.12.11

導入

rails newの雛形作成直後を例に進めます。
hogeモデルとコントローラーを作ります。後からカラムを追加するのは余計なフォームができるのを避けるためです。

bundle install

rails g scaffold hoge url:string

rails g migration AddColumnToHoges title:string description:string

rails db:migrate

バリデーション等考慮すべきですが、今回は動作確認が目的なので省略。 これでURLを登録するフォームができました。
次にスクレイピング部分を実装します。わかりやすいようにいったんcreateアクション内で全て行います。

def create
  require 'open-uri'
  @hoge = Hoge.new(hoge_params)

  html = URI.open(@hoge.url).read
  doc = Nokogiri::HTML.parse(html)

  @hoge.title = doc.css('meta[property="og:title"] @content').to_s
  @hoge.description = doc.css('meta[property="og:description"] @content').to_s

  以下略

require 'open-uri'rubyのライブラリを読み込み。URI.openによりファイルを開くような感覚でhttp/ftpにアクセスできます。

openメソッドでサイトにアクセスし、readメソッドでデータを読込んで内容を変数に保存。

Nokogiri::HTML.parse(html) により取得したデータをパースする。その後cssメソッドで取得したい情報を選択して各属性に保存。 参考記事ではrailsを使用しないrubyファイルだったのでnokogiriのrequireをしていましたが、railsの場合はインストールされているのでなくても使用できました。
https://zenn.dev/arao99/articles/40cde7168279f899d0f5

データ検索条件についてはcssセレクタxpathを使用する方法があり、検索するメソッドもたくさんありました。
https://nokogiri.org/rdoc/Nokogiri/XML/Searchable.html#css-instance_method

ogpについては記載方法が決まっているようなので上記のような方法だと設定されている場合は取得できるはず。
https://ogp.me/

viewに表示部分を追加します。

<p><%= @hoge.title %></p>
<p><%= @hoge.description %></p>

続いて画像の保存部分です。 active storageを使用して保存してみます。最初にインストールを行います。

rails active_storage:install

これにより必要なテーブルを作成するためのマイグレーションファイルが生成されます。 保存先はデフォルトではこんな感じです。 config/strage.yml

test:
  service: Disk
  root: <%= Rails.root.join("tmp/storage") %>


local:
  service: Disk
  root: <%= Rails.root.join("storage") %>

config/environments/development.rbに設定の読み込みを追加します。

config.active_storage.service = :local

画像の加工をしたいのでGemfileの中のimage_processingのコメントを解除してbundle installします。

gem 'image_processing', '~> 1.2'

マイグレーションとgemのインストールを行ったのでサーバー起動中の場合は再起動します。

class Hoge < ApplicationRecord
  has_one_attached :image
end

モデルに関連付けを追加。 createアクションに処理を追加します。

image = doc.css('meta[property="og:image"] @content').to_s
@hoge.image.attach(io: URI.open(image), filename: image)

viewに表示を追加

<div class="">
  <%= image_tag @hoge.image.variant(resize: "200x200") %>
</div>

active storageの使用方法はrailsガイドの記載を参考にしました。 https://railsguides.jp/active_storage_overview.html

これで取得した画像を保存、表示することができました。

URI.openのアクセスについては503エラーとなるサイトがありました。その場合はユーザーエージェントに関する記述を追加すれば同様の処理ができましたが、あまりわかっていないので割愛します。

また、スクリプトによる連続アクセスは攻撃とみなされトラブルになることもあるそうなので気をつけて使用する必要があるとのことでした。

あとは取得した情報を元にCSSを設定すると好みの見た目でリンクを表示できそうです。

railsアプリへのrubocop導入方法

導入の経緯

ポートフォリオ作成に伴いコードの品質確認のためrubocopを導入。
実務上は自分でrubocopの設定を行うことは少ないかもしれないが、個人的に制作するときにも使っていきたいのでメモ。

環境

導入

rails newの雛形作成直後を例に進める。
rubocopのアップデートによる影響を軽減するため、公式サイト記載のようにバージョンを指定。
https://github.com/rubocop/rubocop https://docs.rubocop.org/rubocop/1.12/installation.html https://github.com/rubocop/rubocop-rails

0.72以降はrailsの検証機能が別のgemになっているのでインストールする。
Gemfileに各gemを記載してbundle install

group :development do
  gem 'rubocop', '~> 1.12', require: false
  gem 'rubocop-rails', require: false
end

rubocopコマンドを実行

40 files inspected, 135 offenses detected, 124 offenses auto-correctable

デフォルトだと大量に指摘される。実際には編集しないようなファイルも検査対象となっているので、設定を追加していく。

$ rubocop --auto-gen-config

上記オプションにより設定用ファイルと、現在の指摘の一覧ファイルがapp以下に作成される。

.rubocop_todo.yml  指摘事項の内容と無効化設定
.rubocop.ymal   設定ファイル

rubocop.ymlにはrubocop_todo.ymlの内容を継承する設定が書かれている。最終的にはこの記載を消せるように対応を行っていく。

inherit_from: .rubocop_todo.yml

rubocop-railsの読み込みをrubocop.ymlに追加する。

require:
  - rubocop-rails

rubocop_todo.ymlを一部抜粋

# Offense count: 56
# Cop supports --auto-correct.
# Configuration parameters: EnforcedStyle, ConsistentQuotesInMultiline.
# SupportedStyles: single_quotes, double_quotes
Style/StringLiterals:
  Exclude:
    - 'bin/bundle'
    - 'bin/webpack'
    - 'bin/webpack-dev-server'
    - 'bin/yarn'
    - 'config/environments/production.rb'
    - 'config/puma.rb'
    - 'config/spring.rb'
    - 'test/application_system_test_case.rb'
    - 'test/channels/application_cable/connection_test.rb'
  • 該当項目と数等がわかるので、内容を見て規約上書きか修正対応を行う。
  • 自分が編集することのないディレクトリ等は検査対象から除外すると、ルールを残したまま該当箇所を修正せずに進められる。
  • 全ての項目に対応すると完成

検査事項詳細
https://docs.rubocop.org/rubocop/cops.html

設定方法詳細
https://docs.rubocop.org/rubocop/configuration.html

現時点では全ての指摘を無視しているので再度rubocopコマンドを実行すると指摘はなくなる。

 40 files inspected, no offenses detected

実行時にメッセージが出ている

warning: parser/current is loading parser/ruby26, which recognizes
warning: 2.6.7-compliant syntax, but you are running 2.6.6.
warning: please see https://github.com/whitequark/parser#compatibility-with-ruby-mri.
The following cops were added to RuboCop, but are not configured. Please set Enabled to either `true` or `false` in your `.rubocop.ym
l` file.

Please also note that can also opt-in to new cops by default by adding this to your config:
  AllCops:
    NewCops: enable

Gemspec/DateAssignment: # (new in 1.10)
  Enabled: true
Layout/SpaceBeforeBrackets: # (new in 1.7)
  Enabled: true
  省略
For more information: https://docs.rubocop.org/rubocop/versioning.html

warningについてはrubyのバージョンに関するもの。記載されているURLで詳細が書かれているが、最新のマイナーバージョンの構文に対応しているとのこと。

The following cops were added to RuboCop, but are not configured.は、rubocopの検査事項に以下を追加したが、有効・無効が設定されていないというメッセージ。前のバージョンからのアップデートで自動的に新ルールが適用されるのを防ぐためにこのような表示がされるよう。表示されているルールをどのように扱うかrubocop.ymlに記載することでメッセージが消える。
今回は新規で導入したので全て適用するよう設定。

参考記事
https://qiita.com/ljourm/items/e6691267af176c98cd6b

お手軽vim入門

はじめに

RUNTEQアドベントカレンダー19日目の記事です。
RUNTEQといえばvimなのに、ここまでvimの記事がない!!
ということで、駆け出しvimmerによる非vimmerのための簡単な使い方の紹介記事です。
これから入学する人や他のエディタを使っている人もぜひvimを使ってみましょう!!
まずvimがどのようなものかは下記RUNTEQブログをご覧ください。

Vimを使うと人間にいかなる変化が起きるのか? | RUNTEQ - 公式ブログ

うちのオカンがね、好きなエディタがあるらしいんやけど(vim編) | RUNTEQ - 公式ブログ

素晴らしい記事なので、これだけでvimを使いたくなるでしょ?

操作方法

最初にこれだけ覚えておいてください。
「日本語入力はオフにする」
「ヤバイと思ったら esc :q! で脱出する」

では実際にvimを使って任意のファイルを編集してみましょう。

  • ターミナルを起動し vim ファイル名 でvimを起動します。
$ vim hoge.rb
  • カーソルの移動はh,j,k,lか矢印キーで行います。
  • 文字入力するときはiを押すと編集できるようになります。(インサートモード)
  • インサートモードを終了するときはescキーを押します。
  • vimを終了するときはescキーを押して:q!(保存せずに終了)もしくは:wq(保存して終了)とします。

簡単でしたね!!

時間のある方向け

もっと詳しく知りたいときはvimtutorで基本操作を学びましょう!
ターミナルを起動してコマンドを入力します。

$ vimtutor

するとvimチュートリアルが表示されるのでその通りに進めていきましょう。 基本的な操作はこれで覚えられます。

カスタマイズ

実際にvimを起動してみて、シンタックスハイライトも行数の表示もないの?と思った人もいるかもしれません。
ご安心ください、自分好みにカスタマイズする方法があります。

Vimに興味が出てきたけど難しそうと思った方はカスタマイズしてみて苦手意識を軽減しましょう!!

初期状態のvim f:id:kei-r:20201218033252p:plain

このままでも硬派な感じがしていいのですが、もう少しフレンドリーな見た目にしてみましょう。

まずはターミナルを起動しコマンドを入力します。

$ vim ~/.vimrc

ホームディレクトリに.vimrcという名前のvimの設定ファイルが作成されるので、そこに設定を書きます。

iでインサートモードにして以下のコードを記入します。

syntax on
set number

と記入して、escキー、:wq、Enterで変更内容を保存して終了します。

vimを起動して適当なファイルを開いてください。
行数が表示され、色が変わりました。 f:id:kei-r:20201218041952p:plain

他にもいろいろな設定ができるのでぜひ調べてみてください!!

おわりに

以上簡単にでしたが、vimの操作とカスタマイズについてでした。
私は形から入るタイプなのでRUNTEQの解説動画中でvimの操作画面を見て、めっちゃかっこいい!!と思って使いはじめました。
たくさんのコマンドがあって使いこなすのは難しいかもしれませんが、マウスが使えない以外は他のエディタでも同じだと思うのでこれからプログラミング学習をはじめる人はvimも一緒に覚えましょう!!

参考サイト

はじめてのVim 〜 Vimはいいぞ!ゴリラと学ぶVim講座(1) | さくらのナレッジ

初心者向け vimrcの設定方法 - Qiita

【Rails】rails generateコマンドと元に戻す方法

rails generate scaffoldでファイルを作成した後に処理をやり直そうとしたらつまづいたのでまとめ。 
 
エラーが出たときの処理概要
$ rails generate scaffold hoge
$ rails db:migration
$ rails destroy scaffold hoge
$ rails generate scaffold hoge
$ rails db:migrate (エラー)
 
調べてわかったこと
rails generateで作成されたファイルは、rails destroyで削除できるが、削除前にマイグレーションしたかどうかで元に戻す手順が違うようだった。
 
対応策1:マイグレーション前にファイル削除実行
$ rails generate scaffold hoge
$ rails destroy scaffold hoge
 
対応策2:マイグレーション後はロールバックしてから削除
$ rails generate scaffold hoge
$ rails db:migrate
rails db:rollback
$ rails destroy scaffold hoge
 
対応策3:先に削除したときはデータベースをリセット
$ rails generate scaffold hoge
$ rails db:migrate
$ rails destroy scaffold hoge
rails db:migrate:reset
この場合はデータベースにデータがあったときは消える
 
 
エラーが出たときの動き確認
$ rails generate scaffold hoge
 この時にマイグレーションファイルができる
rails db:migrate
 schema.rbが作成したマイグレーションファイルの内容を元に変更され、バージョン番号が最新になる。
$ rails destroy scaffold hoge
 作成したファイルが全て消えるが、schema.rbの内容は変わらない
$ rails generate scaffold hoge
 再度同名でファイル作成
$ rails db:migrate
 エラー発生:Table “hoges” already exists
 データベース内にすでに同名のテーブルが存在
$ rails db:rollback
 ロールバック試みたがエラー:No migration with version number
 マイグレーションファイルを先に削除しているので見つからない
 Rails内部のshcema_migrationsという名前のデータベース内に、マイグレーションしたときのタイムスタンプが保存されていて、それを参照しているので見つからない
 
作成したファイルの状態とデータベースの状態がどうなっているかを意識しながら処理を進めていかないといけないと思った。
今回はscaffoldで試したが、マイグレーションファイルが作成される処理は他にもあるのでその時も注意していきたい。
 
参考サイト

【Rails】データベースの使用

データを永続化するためにデータベースを使用するので、基本部分のまとめ。
 
データベースとやりとりをするライブラリはActiveRecordで、データオブジェクトの作成、保存、検索のためのメソッドを持っている。
Railsにはマイグレーションという機能があり、データ定義をrubyで記述するのでSQLの文法を書かなくてもデータベースが使える。
 
 

モデルの作成

railsではデータモデルとして扱うデフォルトのデータ構造のことをモデル呼ぶ。モデルとデータベースのテーブルが対応していて、モデルを通じてデータベースを使用できる。
 
$ rails generate model User name:string email:string
 
コントローラ名には複数形が使われたが、モデル名には単数系を用いるのが慣習となっている。
属性と型情報を記載して実行すると対応するカラムをつくることができる。
ActiveRecordを継承したUserモデルが作成されて、このモデルを使用することでデータベースに関するメソッドが使えるようになる。
同時にマイグレーションファイルが生成されテーブル作成のためのchangeメソッドがある。
テーブル名は情報の集まりなので複数形(この場合users)となる。
 

マイグレーションファイルの作成

$ rails generate migration ファイル名

すでにあるテーブルを変更するためのマイグレーションファイルを作成する。
ファイル名はデータベースに加える変更を表すようにしておくと何のためのファイルかわかりやすい。
マイグレーションファイルのchangeメソッドに変更内容を記入する。
以下は変更の例
add_index テーブル名, カラム名, オプション
add_column テーブル名, カラム名, オプション
 

変更内容の反映

$ rails db:migrate
/db/shema.rbがデータベースの構造を追跡するために使われていて、コマンド実行のたびに更新されていく。
マイグレーションファイルを作成、更新した時はこのコマンドにより変更内容を反映する必要がある。
 

ロールバック

$ rails db:rollback
直前に行ったマイグレーションロールバックできる。
STEP=3のようにパラメータをすると最後に行った3つのマイグレーションロールバックされる。
 

seed機能

データベース作成後に初期データを素早く簡単に追加するための機能。
db/seeds.rbにコードを記述して下記を実行する。
$ rails db:migrate:reset
$ rails db:seed
Railsサーバーが起動中だとうまく動かないときがあるので止めてから実行する方が良い。

【Rails】ルーティングの書き方

何回も書いていたら自然と覚えられるものかもしれないが、ルーティングの書き方の基本的なところを復習をした。

routes.rb

ブラウザからのリクエストを各コントローラーのアクションに割り当てるために使われる。
 

get ‘コントローラ名/アクション名’

rails generate controller を実行するときにアクション名を記入しておくと、コントローラー以外にそのアクションに対応するルーティング、ビューファイル等も作成される。このときのルーティングは上記のようになっているが、他の書き方をすることが多い。
 

get  ‘/about', to: ‘static_pages#about’

個別にルートを設定するとき。
GETリクエストが/aboutに送信されたときにstatic_pagesコントローラーのaboutアクションを呼び出す。
このように定義するとURL指定時に/aboutではなく、about_pathやabout_urlといったメソッドを通してURLを参照できるようになる。(名前付きルート)
 
 

root ‘コントローラ名#アクション名’

’/‘がアクションに対応するURL(ルートURL)になる。このときの名前付きルートはroot_pathのようになる。
 

resources :リソース名(複数形)

 restの原則に沿ったルーティングとなり、HTTP動詞、パス、アクションの組み合わせが決まっている。名前付きルートも設定される。

HTTP動詞

 GET、POST、PATCH、DELETEの4種類。
 viewを表示するものはGETリクエストに対応している。
 
パス
 /リソース名で始まる
 アクション名が含まれるのはnewとeditのみ。
 個別の情報に関するものは/リソース名/:id
 
アクション
 7つのアクションに対応する
 index, new, create, show, edit, update, destroy
 

resource :リソース名(単数形)

1つしかないリソースへのルーティングのときに使われる。上記の複数形のときとの違いはindex以外の6つのアクションに対応していることと、パスに/:idが含まれないところ。
 
他にもいろいろな記述方法、機能があるので少しづつ勉強していく。

【Rails】rails new と bundle install

Railsの学習を進める中で何回もbundle installする場面があり、そのときにエラーメッセージの表示が出ることがあったのと、「Gemfileを編集したらbundle installをする」くらいの記憶だったので、Railsでのアプリケーション開発で一番最初に行う2つのコマンドとgemについて復習。
 
RailsのようなWebフレームワークではディレクトリとファイルの構造が標準化されていて、コマンドを入力するとアプリケーションのスケルトンが作成できる。Railsの内部では様々な処理が実行されるので、最低限動く状態にするにはgemのインストールが必要となる。
 
$ rails new app_name
コマンドを実行すると、実行したディレクトリにRailsアプリケーションのディレクトリが作成される。
 
$ rails _6.0.3_ new app_name
実行時にバージョンを指定することで任意のバージョンのRailsで開発を開始できる。
 
$ bundle install 
コマンドを実行することでgemをインストールできる。
rails newによりGemfileが作成されていて、デフォルトでいくつかのgemをインストールするように設定されている。
必要に応じてインストールしたいgemを追記して、再度bundle installを実行する。
このコマンドも実はbundlerというgemの一種を使っている。このパッケージを使うことで複数のgemの依存関係を保ちながらgemの管理をできる。
 
$ bundle update
状況によってはbundle installの前にこのコマンドを実行する必要がある。
 
「gem」という言葉は2つの意味で使われることがある。
  1. Rubyのパッケージ。プログラムの部品で便利な機能を一まとめにしたものをパッケージやライブラリと言う。
  2. 上記パッケージを管理するシステムであるRubyGems。gemパッケージのインストールやアンインストールなどの作業に使われるがbundlerが使われることが多い
 
Gemfile内での記載方法の違いで各gemのバージョンを指定できる。
gem ‘rails
自動的に最新バージョンのgemを取得してインストールする
 
gem ‘rails’, ‘>=6.0.3’
6.0.3以上のバージョンならインストールされる
 
gem ‘rails’, ‘~> 6.0.3’
6.0.3以上で6.1より小さい場合にインストールされる
 
Development環境、test環境、production環境があってどの環境で使用するかも指定できる。
 
参考サイト