みそみそりんりんblog

勉強したことを書いていきます

Rails:Ajaxを使用してリクエストを送った際、Unprocessable Entity 422 となってしまう件について

実行環境

問題

  • js(jQuery)のajaxでcreateアクション(users::books#create)にリクエストを飛ばすとUnprocessable Entity 422となってしまう。

  • Rails側のエラーを見てみると「ActionController::InvalidAuthenticityToken (Can't verify CSRF token authenticity.):」となっていた。

  • どうやら、CSRFトークン認証ができなかったという内容のエラーである。

対応策

解決策1 application_controller.rbを修正

protect_from_forgery with: :null_session

↑この変更により、CSRF対策が『例外の発生』から『セッションのクリア』になる。 『セッションのクリア」の場合、処理は継続されるためAPIのエンドポイントを叩いたら結果が返ってくるようになる。

解決策2 特定のcontrollerを修正

skip_before_action :verify_authenticity_token

↑を追加 影響範囲が限定的になる

参考にしたサイト

【Rails】 API開発で『Can't verify CSRF token authenticity』といわれたときの対応 - Qiita

知っておきたいクロスサイトリクエストフォージェリの仕組み | yamory Blog

RailsのCSRF保護を詳しく調べてみた(翻訳)|TechRacho by BPS株式会社

Rails 7.0.2 => Asset `application.js` was not declared to be precompiled in production. エラーについて

実行環境

問題

app/assets/javascripts/application.jsが読み込めない〜

対応策

Declare links to your assets in app/assets/config/manifest.js.
↑とエラー文にあったため

  //= link_directory ../javascripts .js

を記述

無事、app/assets/javascripts/下のjsファイルが読み込まれるようになりました

ちなみに、特定のViewに読み込ませる際には、

<%= javascript_include_tag "jsのファイル名" %>

↑を記述すればいい

RailsとMinitest まとめ

MinitestとRSpecについて比較

Minitest

  • 処理速度が速い。
  • 元からついている機能が少ないので、拡張する必要がある。
  • ピュアRuby

RSpec

  • 最初からいろんな機能が全部入ってて便利。(多機能)
  • 記述がDSL(可読性良)

Railsテスティングガイドの要約(Minitest)

require "test_helper"

class ArticleTest < ActiveSupport::TestCase
  # test "the truth" do
  #   assert true
  # end
end

上記のコードの説明をしていく。

require "test_helper"

↑ テストで使うデフォルト設定。
このファイルに追加したメソッドはテスト全体で使える。

class ArticleTest < ActiveSupport::TestCase

↑ ArticleTestクラスはActiveSupport::TestCaseを継承することによって、テストケース(test case)をひとつ定義している。これにより、ActiveSupport::TestCaseのすべてのメソッドをArticleTestで利用できる。

ArticleTest < ActiveSupport::TestCase < Minitest::Test

↑という風にMinitest::Testを継承しているので
test ブロック または、 test_で始まるメソッド名で、テストを定義できる。

assert true

アサーションとは、オブジェクトまたは式を評価して、期待された結果が得られるかをチェックするコード
以下のようなチェックを行うことができる。

  • ある値が別の値と等しいかどうか
  • このオブジェクトはnilかどうか
  • コードのこの行で例外が発生するかどうか
  • ユーザーのパスワードが5文字より多いかどうか
エラーの表示内容
F

↑テストが失敗している

E

↑テストコードで、エラーが発生している。

テスト例1 : システムテスト (indexページにh1が存在しているか)

システムテストとは
アプリケーションのユーザー操作のテストに使える。

$ bundle exec rails g system_test articles

require "application_system_test_case"

class ArticlesTest < ApplicationSystemTestCase
  test "viewing the index" do
    visit articles_path
    assert_selector "h1", text: "Articles"
  end
end
テスト例2 : システムテスト続き (ボタンをクリック、値を入力など)
test "should create Article" do
  visit articles_path

  click_on "New Article"

  fill_in "Title", with: "Creating an Article"
  fill_in "Body", with: "Created this article successfully!"

  click_on "Create Article"

  assert_text "Creating an Article"
end
テスト例3 : 結合テスト (ルートにアクセスして、h1タグの中身が"Welcome#index"かどうか調べる)

結合テストとは
複数のコントローラ同士のやりとりをテストする。

$ bundle exec rails g integration_test blog_flow

require "test_helper"

class BlogFlowTest < ActionDispatch::IntegrationTest
  test "can see the welcome page" do
    get "/"
    assert_select "h1", "Welcome#index"
  end
end
テスト例4 : 結合テスト (ブログに新しい記事を1件作成して、生成された記事が表示できてるか?)
test "can create an article" do
  get "/articles/new"
  assert_response :success

  post "/articles",
    params: { article: { title: "can create", body: "article successfully." } }
  assert_response :redirect
  follow_redirect!
  assert_response :success
  assert_select "p", "Title:\n  can create"
end
まとめ

以上の、テスト例くらいの内容は抑えておきたいな〜。

参考文献

Rails テスティングガイド - Railsガイド

NFSでファイルの内容が正しく読み込めない原因について

NFSとは

主にUNIX系OSで利用される分散ファイルシステム、 及び、そのための通信規約(プロトコル)。
ネットワークを介して別のコンピュータの外部記憶装置(ストレージ)をマウントすることができ、そこに保存されているディレクトリやファイルをあたかも手元にあるかのように扱うことができる。
ストレージを他のコンピュータに提供するコンピュータをNFSサーバ、サーバの持つストレージにアクセスして利用するコンピュータをNFSクライアントという。

今回の問題の原因について

同じファイルに対して、
一秒間の間に、
異なるNFSクライアントホストから、
同じサイズのデータを書き込んだ場合に限り発生する。

解決策

アトミックにファイルを更新する(renameというシステムコールを用いる) ↓

inodeが変わるので恐らく回避できる。  
(同じファイルに対してという懸念払拭)  
&&  
アトミックな処理  
(新規にファイルを作成するときには、ファイルの作成途中の中途半端な状態ではなく、ファイルが存在しないか、あるいは作成済みの完全なファイルが存在するかのどちらかになる。)
まとめ

NFSにおいて、 プログラムを通して、 ファイルを作成する際の注意点を把握した。
(アプリケーション側から、読み込まれることを考慮した際)

参考文献

DSAS開発者の部屋:NFS経由で正しい内容が読めない場合がある問題の原因と解決策

そのファイル、安全に更新できていますか?(アトミックなファイル操作:前編) - インフラエンジニアway - Powered by HEARTBEATS

NFS(Network File System)とは - IT用語辞典 e-Words

Rubyのドメイン特化言語(DSL)

ドメイン特化言語(DSL: Domain-Specific Language)

問題領域に特化した言語を意味する
特定の作業の遂行や問題の解決に特化して設計されたコンピュータ言語。
Railsでは、Validations・ActiveRecord・Rake・RSpecなど幅広く使われている。

汎用語(GPL: General Purpose Language) ← DSLの反意語

通常は多種多様な問題に対応できるものを意味する

Rubyで簡単なDSLを書いてみる

DSL定義ファイル

def pay(souvenir)
  puts "結果: #{souvenir}" if yield
end
load 'event.rb'

DSLテスト用のイベントファイル(event.rb)

def souvenir_price
  500 # 実際は、標準入力とか、DBから読み込む
end

my_money = 400

pay "お土産買えた" do
  souvenir_price < my_money
end

pay "お土産買えない" do
  souvenir_price > my_money
end

実行結果

=>  "結果: お土産買えた"
まとめ

今回は初歩の初歩のDSLしか書いていないが、
DSLを書くことにより、非プログラマーの人でも
簡単にイベント定義をすることができる。

参考文献

https://e-words.jp/w/DSL.html

メタプログラミングRuby 第2版 | Paolo Perrotta, 角 征典 |本 | 通販 | Amazon

【Rubyによるデザインパターンまとめ14】DSL(ドメイン特化言語) - 銀行員からのRailsエンジニア

gentoo installでひっかかったとこ

ハンドブック見ながらやったんですけど詰まったところがあったので覚書

CFLAGSとCXXFLAGS変数の設定例

COMMON_FLAGS="-march=native -O2 -pipe"
-O2を0(ゼロ)2ってやってコンパイルエラーになった
気を付けたい

/etc/portage/make.conf ACCEPT_LICENSE変数を変更する

ACCEPT_LICENSE="*"
にしておけばemergeがなんでもインストールしてくれるようになるのでわかんないうちはこれでいいと思います
適当な設定にしておくとgenkernelをはねてくれるのでめんどくさいことになります
FSF教徒は知らん。ガチガチの設定にしてフリーなのだけ使っとけ

カーネルソースのインストール

emerge --ask sys-kernel/gentoo-sources

/usr/src/linux
に入るって書いてあるけど入りません
/usr/src/linux-version-number/
みたいになります
自分でmkdir /usr/src/linuxしてシンボリックリンクつけてください
これやらないとgenkernelがエラー吐きます

コンパイル

これで、カーネルソースを設定、コンパイルする準備が整いました。この設定およびコンパイルには二つのアプローチがあります。

カーネルをマニュアルで設定およびビルドする。
Linuxカーネルを自動的にビルド・インストールするgenkernelを使用する。

ここでは、環境を最適化するのに最も適した"マニュアル設定"をデフォルトとして説明します。

こんなこと言ってるけど素人にはマニュアルは無理
genkernel使って全部入りカーネル作ってもらってください
liveCD動いてるなら動くの作ってくれます

genkernelを使用する

nano -w /etc/fstabでbootだけ設定しておけば
genkernel allで作ってくれます

ネットワークを設定する

config_eth0="dhcp"にすると書いてありますがそもそもeth0かはわからんのでちゃんとifconfigで見てください
自分はenp3s0だったのでなかなかネットにつながりませんでした
起動時に自動でネットワーク接続するをよく参照してください