[Capybara]XPathによる要素の指定方法

以前にも少し似たブログ記事を書きましたが、今回はHTML要素自体がそもそも存在しない場合にfindメソッドで取得しようとした場合に発生してしまうエラーに対して、別の対処方法をご紹介しようかと思います。

以前の記事はこちら

経緯

アプリのある画面でフォームに入力するとアイテムを追加できる機能があり、RSpecにてフォームの必須項目に入力を行わなかった場合にアイテムのリストが追加されていない(表示されていない)かを検証するテストを実装しようとしていました。

その際に、Capybaraのfindメソッドを利用して要素が取得できない場合(nilの場合)はテストをパスするように実装しました。

# id属性値が'#item_id'と設定されている要素を取得して検証してみる
expect(find_by_id('#item_id')).to be_nil

ですが、findメソッドで指定した要素が見つからなかった場合は、nilとはならずにエラーとなってしまう仕様のようです。

解決

対策として要素を取得するのではなく、have_xpathというマッチャを利用して、指定したパスの要素が存在するかを検証するように修正しました。

今回は、フォームの必須項目に入力がなければリストが表示されていないかを検証したかったのでto_notメソッドを使用しています。

expect(page).to_not have_xpath 'パス'

XPathとは

Capybaraで用意されているメソッドなどに利用できるパスです。

HTML内の要素の親子関係についてはパスとして表現できます。

例
/html/body/table/tbody[1]

同階層内に同じタグが複数存在する場合は配列として表現され、配列の開始要素は「1」から始まります。

パスの先頭に「//」が付いているものは、現在のページ全体から特定の要素を指定するためのものです。

# 現在のドキュメントからtbodyタグを検索して取得する
find(:xpath, '//tbody')
# tbodyが複数ある場合、これも同じ結果となる
find(:xpath, '//tbody[1]')
# 2つめのtbodyを取得
find(:xpath, '//tbody[2]')

パスの先頭に「.//」が付いているものは、現在のパスからの相対パスを指定するためのものです。

例えば、以下のような感じで使用することができます。

# ul要素の領域内に絞る
within(:xpath, '//ul') do
  # ul要素配下を対象に要素を指定
  li2 = find(:xpath, './/li[2]')
  a1 = find(:xpath, './/li[1]/a[1]')
end

更新日 : 2020年9月18日

[rails]Capybaraについて

RSpecを実装していて個人的に思うことがあるのですが、RSpecでFactoryBot・Capybaraというライブラリを利用していて、どの部分がRSpecなのかCapybaraなのかが区別がつかないことがあります。

開発者としては、その辺りはしっかりと区別できるようにしておきたいところだなと思い、今回はRSpecの中でも特にCapybaraについて内容を整理しておこうかなと思います。

Capybaraとは

RSpecのテストの際に、ブラウザのページに表示されている部品に対して操作したり検証したりすることができます。

例えば、ブラウザに対してURLを入力してページにアクセスしたり、Webページ内のリンクをクリックしたりする操作を、コードで記述することができます。

そして、テスト結果のページを検証することもできます。

Capybaraは、主にSystemスペックで利用されます。

メソッド一覧

操作系

メソッド 説明
visit visit top_path
visit current_path
指定したURLへアクセスする
ページをリロードする
操作系メソッド一覧

要素の取得

ページ内に存在する要素はオブジェクトとして取得することができます。

メソッド 説明
find find ‘h1’
find ‘.class’
要素の取得
クラス属性による取得
find_by_id find_by_id ‘#id’ ID属性による取得
要素の取得メソッド一覧

取得した要素オブジェクトに対して設定されている属性値を取得することができます。

メソッド 説明
[:属性名]
[‘属性名’]
[:style]
[‘aria-value’]
属性名を指定する
要素の属性値の取得メソッド

検証マッチャ一覧

ページの内容に対して検証を行うことができます。

「expect().to ~」コードの後にマッチャを指定して検証します。

マッチャ 説明
have_content have_content ‘テキスト’ 指定した内容が表示されているか
have_selector have_selector ‘h1’, text: ‘テキスト’
have_selector ‘.class’, text: ‘テキスト’
have_selector ‘#id’, text: ‘テキスト’
CSSセレクタが指定されている要素に指定した内容が表示されているか
検証マッチャ一覧

更新日 : 2020年9月12日

読書まとめ「エンジニアの知的生産術」

著者の西尾 泰和さんの「エンジニアの知的生産術 効率的に学び、整理し、アウトプットする」を読みました。

個人的に印象に残った部分やためになりそうな部分などをまとめておきます。

第一章

知りたいところから

遅延評価的勉強法

情報収集において、一から順を追って調査するのではなく、まずは自分が知りたいと思っているところから調査しましょうといった感じです。

これが「遅延評価的勉強法」と呼ばれています。

自分が今知りたいと思っているところに着目して調べていくことで、最初は断片的にしか知識は得ませんが、そうしていく内に段々と点と点が結びついて最終的には全体像が見えてくる、といった考え方となります。

そして、この方法が良いとされる裏付けとして更に以下の2つを紹介されています。

  • YAGNI原則
  • Matzのソースコードの読み方

「そんなの必要ないよ」YAGNI原則

「必要になるまで機能を追加してはいけない」という原則です。

  • 将来必要な機能かもと気にしすぎて、今やるべき作業に集中できなくなる
  • 仮に実装して、もし不必要になったら時間を無駄にしてしまう

不必要なものに手を出してしまうと、達成するべきゴールまでがその分長くなってしまいます。

ゴールまでが長い分、やる気の維持も難しくなってしまうので、不必要なものには手を出さないようにして極力ゴールまでを短くしていくことが大事になってきます。

Matzのソースコードの読み方

Ruby言語の作者まつもとゆきひろさん(Matz)は、ソースコードの読み方について以下のように言われています。

  • 全体を読もうとしない
  • 目的を持って読む

知りたいところから学ぶための前提条件

目標が明確化

自分が望む結果をより具体的に・明確にします。

  • 「Rubyを勉強する」→「Rubyに関する入門書を読破する」

目標が達成可能である

目標といっても、自分にとって達成しやすい目標へと細分化させます。

そうすることで、具体的にどのような行動を取れば良いのかが分かるようになります。

大まかに全体像を把握している

必要な情報を見つけるために、どこを探しにいけば良いかイメージを掴むことも大事です。

更新日 : 2020年9月21日

VDT症候群の対策

普段から欠かさずにデスクワークを行っていますが、これだけ毎日続けてやっているといつ自分がVDT症候群になってしまうかがとても心配になってきます。

といいますか、既に症状に掛かってしまっているということも無きにしも非ずといった感じですね。

実際、デスクワークを行った後は目の疲れや肩こり・精神的な疲労が顕著に現れていますし。

今のうちにしっかりと対策を打っておかないと大変なことになりそうだと思いますので、今後のためにも対策方法をまとめておこうかなと思います。

VDT症候群とは

VDTとは「Visual Display Terminal」の略で「表示機器」のことを指します。

PCのモニタやタブレット・スマホの画面などがそれに当たります。

VDT症候群は、この表示機器を利用することで発症してしまう病気のことになります。

症状としては、目の疲労に関するものや腰痛・肩こり・頭痛なども伴います。

代表的な症状としては目や首・肩に関連するものが多いとされています。

現状

自分はデスクワークをしていると、よく体が前のめりになったり猫背になったりして、正しい姿勢を維持することができません。

また、作業にはノートPCを利用しているので画面が低い位置にあり自然と頭が下がってしまいます。

そして、作業に没頭してしまって休憩もせずに暫くPCから離れられないこともよくあります。

対策

デスクワーク時の推奨する作業環境を調べてみると、以下のような内容が紹介されていました。

  • 目の位置からPCのモニタの位置は約40cm〜50cm離す
  • 画面の上端は角度10度で見下ろせるように調整
  • 椅子は深く腰をかけて背筋をしっかり伸ばす
  • PCのモニタの反射を遮る
  • 腕と肘が90度開いている状態にする
  • 座面と足の間に指が入るぐらいの幅を空ける
  • 一時間の作業の間に10分〜15分の休憩(モニタを見ない)を挟み、軽い運動をする

僕の場合、実際にできていない項目が幾つか見受けられました。

僕が現在使用しているPCはノート型なので、どうしても位置など調整しづらい箇所が出てきます。

しかし、なるべくならこのような推奨されている作業環境に近づけられるよう、周辺機器など取り揃えるなどして改善できるようにしていこうかなと思います。

あと改善したいことがあったとしても、作業をしていると意識がそれてしまうので、自然に・強制的に改善できる環境作りも大切だなと思います。

例えば、姿勢に関しては今使っている机や椅子を見直してみたり、作業に没頭してしまうのであればタイマーを設定しておいて時間を管理する、というような環境にしていくと良いかなと思います。

LINEモバイルについて

以前から月々の通話料金を抑えたいなと考えていて、やっと決心して大手キャリアからLINEモバイルへと乗り換えることができました。

携帯電話の契約内容など、時間が経つに連れて内容を忘れてしまうことがよくあるので、LINEモバイルについてこの機会にしっかりとまとめておこうかなと思います。

注意)この記事の情報は2020年9月9日時点での情報となりますのでご了承下さい。

概要

LINEモバイルは格安SIMの一つです。

格安SIMは大手キャリアと比べて料金がリーズナブルなものがあり、LINEモバイルに関してはLINEアプリに特化したサービスなども用意されています。

他のキャリアと比べて内容がシンプルなのも良い点ですね。

LINEモバイルならではの特徴に関して以下のようなものがあります。

  • LINEや主要SNSのデータ通信量が無料になるオプションがある
  • LINEを通じて友達にデータ通信量をプレゼントすることができる
  • LINEの年齢認証機能・ID検索に対応
  • 「いつでも電話」アプリで通話料が半額
  • LINEポイントで月々の料金を支払える

料金プラン

料金プランの選び方は以下の3つの組み合わせとなります。

  1. SIMタイプ
  2. データ容量
  3. データフリーオプション

SIMタイプ

SIMタイプには、①音声通話SIMと②データSIMの二種類があります。

音声通話SIMは、通話が可能なタイプのSIMとなります。

それに対してデータSIMは、通話ができないタイプのSIMとなります。

データ容量

ネットの閲覧やデータのダウンロード時に利用できる通信容量です。

この決められた容量を超えてしまうと、速度制限が掛かってしまい通信速度が落ちてしまいます。

データ容量は四種類から選べます。

  • 500MB
  • 3GB
  • 6GB
  • 12GB

データフリーオプション

LINEや主要SNSの利用時のデータ通信量が掛からなくなるオプションです。

もし所持しているデータ容量を使い切ってしまったとしても、通信速度が落ちなくなります。

データフリーオプションには三種類あり、オプションによってデータフリー対象のアプリが変わってきます。

  • LINEデータフリー(無料) : LINE
  • SNSデータフリー : LINE・Twitter・Facebook
  • SNS音楽データフリー : LINE・Twitter・Facebook・Instagram・LINE MUSIC・Spotify・AWA

解約時の注意点

SIMを返却しなければならない

解約後はSIMを所定の住所へ返送しなければいけません(送料は自己負担)。

解約事務手数料が掛かる

LINEモバイルを解約、又はMNP転出をした際の手続きで必要となる費用(1000円)です。

エルゴヒューマン(ベーシック)のレビュー

普段デスクワークの時間が多いので作業環境も快適にしたいなと思い、エルゴヒューマンというオフィスチェアを購入しました。

使用してから暫く経つので、エルゴヒューマンのレビューについて書こうかなと思います。

使用しているエルゴヒューマンの仕様は以下となります。

  • エルゴヒューマン ベーシック
  • エラストメリックメッシュ素材
  • ヘッドレスト付き

エルゴヒューマンとは

座り心地を追求した、高機能なオフィスチェアです。

エルゴヒューマン(Ergohuman)の語源は、人間工学(エルゴノミクス)から来ていて、その名の通り人間工学に基づいた設計がされています。

各部分で細かな調節機能が備わっており、このカスタマイズ性のおかげでより体へのフィット感が増します。

そして何より一番の特徴としては、腰を支える「独立式ランバーサポート」というものが備わっていて、背もたれと独立した構造となっています。

このような構造となっているので、腰をしっかりと支えて負担を和らげてくれるので腰痛への対策にもなります。

タイプは幾つかあり、ベーシック・エンジョイ・プロなどがあります。

エルゴヒューマン以外にも、アーロンチェアなど高級なオフィスチェアは存在しますが、こちらのエルゴヒューマンは割とリーズナブルな部類の方で、大体10万前後あたりで購入できます。

調節箇所

色々な箇所で細かな調整が可能なので、自分の体にフィットする形へと近づけることができます。

各部分で調節可能な箇所は以下の通りとなります。

  • 背もたれ高さ調整
  • ヘッドレスト高さ&角度調整
  • アームレスト高さ&左右角度&前後左右スライド調整
  • 座面高さ&前後スライド調整
  • リクライニング硬さ調整

良い点

座り心地はサイコーに良いです

エルゴヒューマンだとランバーサポートの加減が良くて楽々に深く座ることができます。

そして、背もたれ・ヘッドレストの部分がしっかりと体にフィットするので、正しい上体の姿勢を楽にキープできます。

この状態でデスクワークができるので、姿勢が悪くなったりすることがなく体に負担が掛かりにくくて良いですね。

キーボード打つのが楽になった

アームレストの高さ&左右傾き&前後左右スライドの調節機能のおかげで、肘への負担が大分なくなったと感じておりとても楽になりました。

PCのキーボードを打つときは、アームレストの傾きを内側へ最大に傾けるようにしています。

シンプル

ものによっては操作レバーが2つ付いているものがありますが、エルゴヒューマンは1つだけなのでシンプルです。

一つのレバーで座面の位置調節とリクライニングの切替えができます。

各部の調節機能も単純な操作でできてしまうのでそこも良い点ですね。

デザインがカッコいい

僕はベーシックタイプ(黒)でメッシュ素材のものを購入しましたが、黒とメタリックな配色など見た目がとてもカッコいいです。

背もたれの支えやキャスターのフレームにはアルミ素材が使われていて質感も良いです。

悪い点

値段が高い

他の高級チェアと比べたらまだマシな方かもしれませんが、それでも中々手が出しにくい値段ではあるかなと思います。

重たい

本体の重量はとても重たいので、持ち運びとかを考えるとおしい部分ですね。

僕はハイタイプ・メッシュ素材なので重量は25.6kgです。

総合的には満足

普段はデスクワークで過ごすのが大半なので、長い目でみたら良い投資にはなったのかなと思います。

更新日 : 2020年9月9日

[Git]ブランチの操作

Gitにはブランチ(枝)という概念があります。

個人で開発されている場合であれば、ブランチを利用しなくとも開発はできなくはないのですが、複数人での開発の場合は利用が必須の場合が殆どです。

最初は取っつきにくいものですが、知っておくと便利なものなので覚えておいて損はないと思います。

今回は、Gitのブランチの操作についてまとめておきたいと思います。

現在のブランチの確認

現在どんなブランチが存在するのかを確認したい場合、以下のコマンドを実行することで確認することができます。

ローカルのブランチ
$ git branch

リモートのブランチ
$ git branch --remote

ブランチの作成

以下のコマンドを実行することで、新たにブランチを作成することができます。

$ git branch [ブランチ名]

このままではブランチが作成されただけで、ブランチに移動できていません。

ブランチを移動する場合は、checkoutコマンドを実行します。

$ git checkout [ブランチ名]

ブランチの削除

ブランチを削除したい場合、branchコマンドに続けて–deleteオプションを付けて実行することでブランチを削除することができます。

$ git branch --delete [ブランチ名]

マージ

現在のブランチに取り込みたいブランチを指定する場合、mergeコマンドを実行します。

$ git merge [ブランチ名]

[おまけ]ブランチ名について

僕が実際に使用しているブランチ名の命名規則について紹介しておきたいと思います。

masterブランチ

リリース用のブランチです。

なので、このブランチは正式なバージョンで動作することが保証されているので、作業中のものは一切含めたりはしません。

devブランチ

開発中のバージョンのブランチです。

開発中のシステムがまだ正常に動作することが保証されていない可能性のあるブランチで、機能が一通り実装できたものをどんどんdevブランチに追加していきます。

devブランチのバージョンで問題無く動作することが確認できたらmasterブランチへマージします。

workブランチ

一部の機能を実装中のブランチです。

機能が一通り実装できたらdevブランチへマージします。

[Git]操作の基本の流れ

Gitの操作方法について、ついつい忘れてしまいがちなので今一度しっかりとまとめておきたいと思います。

今回は、とくに実作業でよく使うGitの操作について触れていこうと思います。

ファイルの追加

変更したファイルをコミットする前に、ステージという領域に対象のファイルを追加する必要があります。

その場合はaddコマンドを利用します。

特定のファイルを追加
$ git add aaa.txt

全ての変更ファイルを追加
$ git add .

コミット

ステージに登録されているファイルをリポジトリにコミットします。

コミットする場合はcommitコマンドを実行します。

$ git commit -m 'コミットメッセージ'

-mは、続けてコミットメッセージを入れることができるオプションです。

履歴の確認

コミットした履歴(バージョン)を確認したい場合、logコマンドを実行します。

$ git log

プッシュ

ローカルリポジトリに登録されている内容を、リモートリポジトリに反映する場合はpushコマンドで実行します。

$ git push

状態の確認

Gitの現在の状態を確認する場合、statusコマンドを実行します。

$ git status

実行すると、git管理内のファイルが今どんな状態なのかを確認することができます。

更新日 : 2020年9月8日

[Rails]検索機能の実装(ransack)について

現在開発中のRailsアプリに検索機能を実装したいと思い、簡単に実装ができるgemとか何かないかなと調査してみました。

そしたら、検索機能にはransackというgemがよく利用されていることが分かり、ransackを導入することに至りました。

今回は、このransackというgemについてまとめていきたいと思います。

ransackとは

検索機能を簡単に実装することができるgemです。

検索機能以外にもソート機能も利用することができます。

検索機能は自前で実装しようとするとかなり手間が掛かると思われるので、簡単に実装できるようになるのは中々便利ですね。

導入

ransackはgemのパッケージとなっているので、gemfileに以下のコードを追加しgemをインストールします。

gem 'ransack'

はい、これでransackを利用する準備が整いました。

利用方法

検索機能

まずは、コントローラー側の処理を実装します。

画面に表示されている検索フォームにユーザーが入力し、サーバー側で検索用のパラメータを受け取ることを想定します。

そして、その情報を基にモデルを抽出する処理を実装します。

# 検索フォームの情報を基にSearchオブジェクトを作成
@q = User.ransack(params[:q])
# 検索結果の取得
@users = @q.result(distinct: true)

因みに、ransackメソッドは以前はsearchメソッドだったので間違って利用しないように気をつけましょう。

# 古いバージョン
@q = User.search(params[:q])

コントローラー側の実装が完了したら、次は画面に表示させる検索フォームを作成します。

テンプレートに以下のようなフォームを作成します。

= search_form_for @q do |f|
  f.label :name
  f.search_field :name_cont

  f.submit

ransackのヘルパーメソッドsearch_form_forに、コントローラー側で取得したSearchオブジェクト(@q)を引数として渡します。

そしてブロックの中に、Railsのform_withメソッドのようにフォームのタグを配置していきます。

ポイントとしては、フォームの引数にカラム名を指定していますが、このシンボル名の末尾に検索条件のマッチャを記述します。

こうすることで、フォームに入力した内容に対して検索条件を指定することができます。

ソート機能

ソートさせたいカラムに対してソートさせるためのリンクを貼ることができます。

その場合、ransackのヘルパーメソッドsort_linkを利用します。

例えば、モデルの名前属性(name)にソートさせるリンクを貼りたい場合、テンプレートに以下のようなコードを追加します。

= sort_link(@q, :name)

そうするとカラム名の部分がリンクとなり、クリックする毎に昇順・降順でソートされるかと思います。

検索マッチャ一覧

ransackで利用できるマッチャは以下の通りです。

ワード 説明
*_eq
*_not_eq
等しい
等しくない
equal
not equal
*_gt
*_gteq
よりも大きい
よりも大きい(等しいものも含む)
grater than
grater than or equal
*_lt
*_lteq
よりも小さい
よりも小さい(等しいものも含む)
less than
less than or equal
*_cont 部分一致 contains value
*_or_* 複数のカラムから検索
検索マッチャ一覧

更新日 : 2020年9月7日

[ransack]NoMethodErrorが出力される

開発中のRailsアプリに検索機能が既に実装されていて、新たに検索項目を追加しようとしましたが、原因不明のエラーが出力されてしまいました。

今回は、僕が遭遇したエラーに関する解決方法をシェアしていきたいと思います。

やったこと

アプリには既に検索機能が実装されていたので、新しく検索フォームの項目(検索対象のカラム)を追加しました。

その時に追加したコードは以下のような感じでした。

= search_form_for @q do |f|
  ...
  / 追加したコード
  f.search_field :created_at

コードの追加後、アプリを実行してみると「NoMethodError」というエラーが表示されてしまいました。

ネットで調査してみましたが、中々解決方法が見つからず一時間ぐらいエラーに悩まされていましたw

原因

解決方法は簡単な話で、モデル側に実装しているransackable_attributesメソッドの返り値に検索対象のカラムが追加されていなかったので、配列にカラムを追加したら解決しました。

def self.ransackable_attributes(*)
  # 配列に追加
  %w[created_at]
end

自分でメソッドを用意していたにも関わらず、カラムを追加しなきゃいけない事を忘れていましたw

ransackable_attributesメソッド

このメソッドは、検索の対象にしたいカラムを指定することができます。

指定方法は、メソッドの返り値として検索対象のカラム名をシンボルとして格納した配列を返すようにします。

このメソッドを利用することで、意図しないカラムまで検索対象にしてしまうことを予め防ぐことができます。

更新日 : 2020年9月5日