- 投稿日:2020-10-19T23:45:32+09:00
deviseの導入
Railsでdeviseの導入流れ
1. Gemをインストールしてサーバーを再起動
2. コマンドを利用してdeviseの設定ファイルを作成
3. コマンドを利用してUserモデルを作成
4. 未ログイン時とログイン時でボタンの表示を変える実装
5. コントローラーにリダイレクトを設定
deviseのgemインストール
Gemfile# 中略 gem 'devise'ターミナル# サーバーを起動 % rails sコマンドを実行して設定ファイルを作成
ターミナル# deviseの設定ファイルを作成 % rails g devise:installコマンドを実行してUserモデルを作成
ターミナル# deviseコマンドでUserモデルを作成 % rails g devise userマイグレーションを実行
ターミナル# マイグレーションを実行 % rails db:migrateローカルサーバーを再起動
ターミナル# 「ctrl + C」でローカルサーバーを終了 # 再度、ローカルサーバーを起動 % rails sリダイレクト処理を用意
app/controllers/tweets_controller.rbclass TweetsController < ApplicationController before_action :set_tweet, only: [:edit, :show] before_action :move_to_index, except: [:index, :show] def index @tweets = Tweet.all end def new @tweet = Tweet.new end def create Tweet.create(tweet_params) end def destroy tweet = Tweet.find(params[:id]) tweet.destroy end def edit end def update tweet = Tweet.find(params[:id]) tweet.update(tweet_params) end def show end private def tweet_params params.require(:tweet).permit(:name, :image, :text) end def set_tweet @tweet = Tweet.find(params[:id]) end def move_to_index unless user_signed_in? redirect_to action: :index end end endコマンドを実行してdevise用のビューを作成
ターミナルrails g devise:viewsusersテーブルにnicknameカラムをstring型で追加
ターミナル# ディレクトリがpictweetであることを確認 % pwd # usersテーブルにnicknameカラムをstring型で追加するマイグレーションファイルを作成 % rails g migration AddNicknameToUsers nickname:string # 作成したマイグレーションを実行 % rails db:migrateターミナル# 「ctrl + C」でローカルサーバーを終了 # 再度、ローカルサーバーを起動 % rails sapplication_controller.rbを編集
app/controllers/application_controller.rbclass ApplicationController < ActionController::Base before_action :configure_permitted_parameters, if: :devise_controller? private def configure_permitted_parameters devise_parameter_sanitizer.permit(:sign_up, keys: [:nickname]) end end以上です!
deviseには元々デフォルトでemailとpasswordは内部で動いてくれているのでカラムを追加しない場合はパラメーターに記述不要です!
- 投稿日:2020-10-19T23:28:16+09:00
地味に大切だった命名規則。もう二度と間違えない!
はじめに
本日の学習で出会ったエラーが、今まででいちばん意外なところでのエラーだったので、忘れないために記録しておく。
命名規則
クラス名はアッパーキャメルケースで記述する。
アッパーキャメルケース:先頭の単語と、単語の区切りの頭の文字を大文字にする。
キャメルケース:先頭は小文字で、単語の区切りの頭の文字は大文字にする。
スネークケース:単語と単語の区切りをアンダースコア(_)で繋げる。クラス名→アッパーキャメルケース
変数名・メソッド名→スネークケース最後に
本日の学習では、処理の記述を何度見返しても、違いが見つからず、単語を繋げたクラス名をスネークケースで記述してしまい、クラスを読み取らないというエラーが出てしまった。
ちまみに、キャメルはラクダ。大文字のところが、コブってこと。アンダースコアは蛇に見えるか?
- 投稿日:2020-10-19T23:17:05+09:00
【Ruby】Your Ruby version is 2.6.3, but your Gemfile specified 2.5.8
はじめに
Rubyを触っていたときにタイトルのエラーが出たので記事にしました。
エラーとの遭遇
作成途中だったアプリを触っていたときに、
bundle install
でエラーに遭遇。$ bundle install -> Ruby version is 2.6.3, but your Gemfile specified 2.5.8エラー文から、RubyのバージョンとGemfileが指定してるバージョンが違うんだろうなーと検討がつく。
対応したこと
まず、Rubyのバージョンを確認してみる。
$ ruby -v -> ruby 2.5.8p224 (2020-03-31 revision 67882) [x86_64-darwin19]rbenvを使用しているので、そちらでも確認
$ rbenv versions system 2.1.5 2.5.1 * 2.5.8 2.6.3 2.7.1見た感じは合ってるっぽい。
今使っているRubyのパスを参照したりできる
gem environment
で確認してみよう。$ gem environment -> RubyGems Environment: - RUBYGEMS VERSION: 2.7.6.2 - RUBY VERSION: 2.5.8 (2020-03-31 patchlevel 224) [x86_64-darwin19] - INSTALLATION DIRECTORY: /Users/username/.rbenv/gems/2.5.0 - USER INSTALLATION DIRECTORY: /Users/username/.gem/ruby/2.5.0 - RUBY EXECUTABLE: /Users/username/.rbenv/versions/2.5.8/bin/ruby - EXECUTABLE DIRECTORY: /Users/username/.rbenv/gems/2.5.0/bin - SPEC CACHE DIRECTORY: /Users/username/.gem/specs - SYSTEM CONFIGURATION DIRECTORY: /Users/username/.rbenv/versions/2.5.8/etc - RUBYGEMS PLATFORMS: - ruby - x86_64-darwin-19 - GEM PATHS: - /Users/username/.rbenv/gems/2.5.0 - GEM CONFIGURATION: ...(続く)うーん、間違ってなさそう...
解決した方法
bundle の配置場所を確認してみる
$ which bundle -> /usr/local/bin/bundle中身を見てみる
-> % cat /usr/local/bin/bundle #!/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby # # This file was generated by RubyGems. # # The application 'bundler' is installed as part of a gem, and # this file is here to facilitate running it. # require 'rubygems' version = ">= 0.a" str = ARGV.first if str str = str.b[/\A_(.*)_\z/, 1] if str and Gem::Version.correct?(str) version = str ARGV.shift end end ...(続く)あ、
/System/Library/Frameworks/Ruby.framework/Versions/2.6/usr/bin/ruby
を参照しているぞ...$ which ruby /Users/username/.rbenv/shims/ruby参照先を
/Users/username/.rbenv/shims/ruby
に変更。無事
bundle install
が通りました!参考記事
https://qiita.com/h5y1m141@github/items/74029cab9706971c8dbe
- 投稿日:2020-10-19T23:03:34+09:00
pluckメソッドとは
今回、pluckメソッドについて学習したため、アウトプットいたします。
pluckメソッドとは?
その使い方とは?について記述いたします。
pluckメソッドとは?
pluckメソッドとはこう書かれています。
「引数に指定したカラムの値を配列で返すメソッド。」同様の効果のあるメソッドとしてmapメソッドが上げられますが、返り値を配列として取得する場合は、pluckメソッドを使った方がシンプルで楽です。
では実際に使ってみましょう。
使い方
usersテーブルのnameカラムに"田中", "吉田", "鈴木", "高橋"の4人が入っていたとする。
そこで、userテーブルのnameカラムだけ取得したい場合、pluckメソッドは力を発揮するUser.pluck(:name) #すると以下のような処理がされる SELECT `users`.`name` FROM `users` => ["田中", "吉田", "鈴木", "高橋"] # 返り値このようにテーブルやデータベースに登録された情報を配列としてまとめて取得したい場合にとても便利です。
- 投稿日:2020-10-19T20:27:32+09:00
Kinx ライブラリ - 自動組版(Tiny Tyesetting)
はじめに
「見た目は JavaScript、頭脳(中身)は Ruby、(安定感は AC/DC)」 でお届けしているスクリプト言語 Kinx。今回は Tiny Typesetting 最新情報です。これ の続きです。
- 参考
- 最初の動機 ... スクリプト言語 KINX(ご紹介)
- 個別記事へのリンクは全てここに集約してあります。
- リポジトリ ... https://github.com/Kray-G/kinx
- Pull Request 等お待ちしております。
ココんトコロ、こればかりやってました。はい。一先ず最初にやりたかったことはある程度できるようになりましたので、公開します。
ライブラリというより、単機能として使用できるよう KiTTy って名付けてあります(今時点では)。
kxkitty.exe
(Windows) とkxkitty
(Linux) という実行コマンドも用意しています。ひとまず、マニュアルをエッサホイサと作ったので、それを参照してみてください。マニュアル自体を KiTTy で作成しています(日本語と英語両方作るのは大変だった...)。ここでは日英両方載せておきます。英語はざざーっと仕上げることを優先したので、かなり自信ありません。
元のファイルはこれです。
- https://github.com/Kray-G/kinx/blob/master/examples/typesetting/KiTTy_jp.md
- https://github.com/Kray-G/kinx/blob/master/examples/typesetting/KiTTy_en.md
これを KiTTy 処理すると以下のようになります。自信はないですが、英語版も載せておきましょう。
- https://github.com/Kray-G/kinx/raw/master/examples/typesetting/KiTTy_jp.pdf
- https://github.com/Kray-G/kinx/raw/master/examples/typesetting/KiTTy_en.pdf
どうでしょう?
ちなみに処理速度は今のところ遅いといえば遅いのですが、私個人的にはまぁ我慢できます(私の子なので贔屓目だとは思います)。実行速度を向上できるだろう改善のアイデアはあるのですが、ちょっと時間的な余裕がないのでしばらくはこのままでしょう。あらかじめご容赦いただけるよう先に謝っておきたいと思います。すみません。
使っている技術情報などなど
サポート機能一覧
マニュアルにも載せていますが、KiTTy は組版機能として以下の機能をサポートしています。なお、カーニングは現在サポートしていません。詳しくはマニュアルを読んでみてもらえると嬉しい。
- 基本組版機能
- ハイフネーション・ジャスティフィケーション・行分割
- ウィドウ/オーファン
- マルチカラム
- 箇条書き
- 数式
- イメージ
- グラフ(チャート)
- テーブル
- フォント
- 色
- 合字・特殊文字
- プログラム・コード
- タイトル・カバーページ・目次
- 見出し
- 相互参照
- 引用
- 脚注
- 日本語用組版機能
- 日本語禁則処理
- 日本語ルビ
- PDF 機能
- 外部リンク
- 相互参照リンク
- しおり
日本語組版機能も一部サポートしています。ルビも振れます。縦書きはサポートしていません。
主要な個別技術情報
せっかくの技術ブログなので、技術情報を少々。
Knuth-Plass Line Breaking Algorithm
LaTeX で使われている行分割のアルゴリズムです。ハイフネーション処理をした後、個別の Box 単位に Glue と Penalty を挿入し、Penalty が最小になる位置で改行するようにコントロールします。
技術的な詳細は、日本語だと以下が参考になるでしょう。
また、実装は、以下(BSD-2-Clause License)を修正して利用させていただきました。見た目は JavaScript の本領発揮です。
数式
LaTeX を目指す(目指してはいませんが)なら数式が必要です。そこで、JavaScript には KaTeX とか MathJax とかあるので、ここでも 見た目は JavaScript の特長を生かして進めようと思いましたが、細部(フォントとか CSS が必要とか)が違い過ぎて 無理でした。なので、ここでは Duktape + KaTeX で実装しました。が、しかし、レンダリングで躓き、結局最終的には Phantomjs ベースで画像化します。Duktape は必要だったのか、という気もしますが、Duktape は他でも使いようがあるかもしれないので、まぁこのままでいいかな、と実装はステイにしました(修正する時間もあまりなく)。
なお、今時点で Phantomjs を使うのは微妙、という声もちらほらググると出てきますが、動いているので良しとします。node.js とか Chrome とか使わずに単一コマンドでできるのでライブラリ内に閉じて良いと思ってますが、他の手段でも「そう(単一コマンドだけで閉じる感じに)できますよ」という情報があれば下さい。
Chart.js
Phantomjs を内蔵したので、色々できるのでは、と最初にチャレンジしたのがうまくいきました。文書内に自由にチャートをかけるのは非常に便利な気がします。というか便利ですよね。
ちなみに、気をよくして Mermaid.js を組み込もうとして失敗しています(UMLとか書けるといいなー)。そのうち再チャレンジするかもしれません。
その他
その他も紹介できそうなものは色々ありそうですが、時間的制約から本日はここまで。
インストール方法
インストール方法もマニュアルに載っていますが、紹介しておきます。元が Markdown なので、基本コピーな感じでいけますね(ちょっと修正が必要ですが)。
インストールは以下の 2 ステップを実施します。
- Kinx のインストール
- KiTTy 追加モジュールのインストール
ちなみに、Kinx コアモジュールは 8.5~9M 程度ですが、KiTTy 追加モジュールは(フォントとかも含まれていて)74M くらいあります。ここ(リリースページ) の Assets を見ると分かります。パッケージマネージャーを作るのは大変なので、全部コアに入れない方法を模索しました。パッケージマネージャー相当は今後用意したいですが、今はこの方法で。
Linux
Linux では以下のようにモジュールをダウンロードします。
v0.15.2
は KiTTy ライブラリが正式に追加されたバージョンです。
最新バージョンを使用する場合は書き換えてください。
ワークディレクトリを作成し、移動してください。$ mkdir temp $ cd temp最初に kinx モジュールをダウンロードし展開し、
次に KiTTy パッケージをダウンロードして展開します。$ curl -L \ https://github.com/Kray-G/kinx/releases/download/v0.15.2/package_linux-amd64.tar.gz \ --output package_linux-amd64.tar.gz $ tar -xvf package_linux-amd64.tar.gz $ curl -L \ https://github.com/Kray-G/kinx/releases/download/v0.15.2/package_kitty.zip \ --output package_kitty.zip $ unzip package_kitty.zip展開するとバージョン番号のフォルダができますので、
移動してinstall.sh
コマンドを実行します。$ cd v0.15.2 $ sudo ./install.shこれでインストールは完了です。
実行フィルの位置1を確認してみましょう。$ which kxkitty /usr/bin/kxkittyWindows
Windows では Release ページ から最新のパッケージ(以下 2 点)をダウンロードします。
- package_win64.zip
- package_kitty.zip
それぞれ展開し、
package_kitty.zip
の中身を lib フォルダ配下にコピーします2。その際、lib 配下に fonts、phantomjs フォルダが配置されるようにしてください。
圧縮ファイル内のファイル構成が必ずしもそうなっていない可能性があります。ビルド
通常、ビルドから実施する必要はありません。
既にビルドされた実行モジュールが提供されており、手順にしたがってインストールを実施することで本システムを利用することができます。
あえてビルドから実行したい、といった場合は以下の手順によってビルドを実施できます。Linux
Github よりクローンし、make します。
$ git clone https://github.com/Kray-G/kinx.git $ cd kinx $ makeインストールします。
$ git clone https://github.com/Kray-G/kinx.git $ cd kinx $ sudo make install $ sudo make kitty-installWindows
Github よりクローンし、make します。
$ git clone https://github.com/Kray-G/kinx.git $ cd kinx $ make.cmd特に現在はインストール用のコマンドを用意していませんが、
ビルドした環境で使用可能です。
ビルドした環境でご使用ください。hello, world
次の文書を作成し、
helloworld.md
ファイルとして保存します。% Hello Kinx Tiny Typesetting % Your name % October 7, 2020 <param style="ArticleA4"/> # Greeting hello, world以下のように
kxkitty
コマンドを実行することで、helloworld.pdf
が作成されます。$ kxkitty helloworld.mdなお、現在はサンプル程度の記載が必要ですが、
もう少しシンプルなサンプルを提示できるよう改善する予定です。おわりに
多少なりとも「まぁまぁいいんじゃない?」と思いましたら、GitHub スターくれると嬉しいです(いつも同じこと言ってますが)。また、これまで色々と応援してくださっている方々にもあらためて感謝します。ちょっと更新が遅くなり気味な近頃ですが、ちょっとずつ進めていきたいと思いますので、GitHub 上で Issue なり Pull Request なりいただけると大変有難く思います。
では、今後ともよろしくお願いいたします。
- 投稿日:2020-10-19T19:19:54+09:00
【Ruby on Rails】RSpecでのモデルテスト
開発環境
ruby 2.5.7
Rails 5.2.4.3
OS: macOS Catalina前提
【Ruby on Rails】RSpec導入まで
こちらが出来ている前提で進めます。modelのテスト準備
・バリデーションの設定
今回はタイトルカラムがあるかどうかと文字数のテストします。
app/models/post.rbclass Post < ApplicationRecord belongs_to :user validates :title, presence: true, length: {maximum: 20} end・ファイルの作成
①
spec配下にmodelsフォルダとfactoriesフォルダを作成し、
テストしたいモデルのファイルも作成します。
今回はpostモデルをテストします。
またユーザーがログインしている状態でしか投稿できないようにするために、
useモデルも作成します。
ファイル構成は下記の状態です。
spec/models/post_spec.rb
→テストしたい内容を記述しますspec/factories/post.rb
spec/factories/user.rb
→ダミーデータを作成します②
FactoryBotを使えるようにします。
使用するとuser = create(:user) のようにDB登録やモデルのビルドができるため便利です。
spec配下にsupportフォルダとfactory_bot.rbファイルを作成し、下記のように記述します。spec/support/factory_bot.rbRSpec.configure do |config| config.include FactoryBot::Syntax::Methods endその後、下記を追加します。
spec/rails_helper.rb# This file is copied to spec/ when you run 'rails generate rspec:install' require 'spec_helper' ENV['RAILS_ENV'] ||= 'test' require File.expand_path('../config/environment', __dir__) # Prevent database truncation if the environment is production abort("The Rails environment is running in production mode!") if Rails.env.production? require 'rspec/rails' require 'support/factory_bot' # <ーーー 追加 ...実際のコード
まずはダミーデータを作成します。
spec/factories/user.rbFactoryBot.define do factory :user do email { Faker::Internet.email } phone_number { 12345678909 } password { 'password' } password_confirmation { 'password' } end endspec/factories/post.rbFactoryBot.define do factory :post do body { Faker::Lorem.characters(number:20) } user end end次にテストコードを記述します。
spec/models/post_spec.rbrequire 'rails_helper' RSpec.describe 'Postモデルのテスト', type: :model do describe 'バリデーションのテスト' do # factoriesで作成したダミーデータを使用します。 let(:user) { FactoryBot.create(:user) } let!(:post) { build(:post, user_id: user.id) } # test_postを作成し、空欄での登録ができるか確認します。 subject { test_post.valid? } let(:test_post) { post } context 'titleカラム' do it '空欄でないこと' do test_post.title = '' is_expected.to eq false; end it '20文字以下であること' do post.title = Faker::Lorem.characters(number:21) expect(post.valid?).to eq false; end end end describe 'アソシエーションのテスト' do context 'customerモデルとの関係' do it 'N:1となっている' do expect(Post.reflect_on_association(:user).macro).to eq :belongs_to end end # has_manyの関係性で記述するのもありです。 # context 'PostCommentモデルとの関係' do # it '1:Nとなっている' do # expect(Post.reflect_on_association(:post_comments).macro).to eq :has_many # end # end end endその後、ターミナルで下記を実行してください。
$ rspec spec/modelsテストを通過すると
Finished in 0.52408 seconds (files took 2.11 seconds to load) 3 examples, 0 failuresこのように表示されるためテスト内容が正しいことを表しています。
逆にテストを通過しない場合、このような形でどこでエラーが起きているかわかるので、
テストコードが間違っているのか、バリデーションが間違っているかなどがわかるようになります。Failures: 1) Postモデルのテスト バリデーションのテスト titleカラム 20文字以下であること Failure/Error: let!(:post) { build(:post) } NoMethodError: undefined method `build' for #<RSpec::ExampleGroups::Post::Nested::Title:0x000000000619e938> # ./spec/models/post_spec.rb:9:in `block (3 levels) in <top (required)>' 2) Postモデルのテスト バリデーションのテスト titleカラム 空欄でないこと Failure/Error: let!(:post) { build(:post) } NoMethodError: undefined method `build' for #<RSpec::ExampleGroups::Post::Nested::Title:0x0000000007491518> # ./spec/models/post_spec.rb:9:in `block (3 levels) in <top (required)>' Finished in 0.07992 seconds (files took 2.41 seconds to load) 2 examples, 2 failures Failed examples: rspec ./spec/models/post_spec.rb:11 # Postモデルのテスト バリデーションのテスト titleカラム 20文字以下であること rspec ./spec/models/post_spec.rb:15 # Postモデルのテスト バリデーションのテスト titleカラム 空欄でないことまた下部にあるrspec ./spec/models/post_spec.rb:11を使い、
下記のように個別にテスト内容を確認することも出来ます。ターミナル$ rspec spec/models/post_spec.rb:11まとめ
今回は
1,空白での登録を防ぐバリデーション presence: true
2,文字数制限のバリデーション length: {maximum: 20}
3,リレーションの関係性の確認 belongs_to :user上記をテストしましたが、この他にも色々テスト方法があるため、
興味のある方は調べてみてください。またtwitterではQiitaにはアップしていない技術や考え方もアップしていますので、
よければフォローして頂けると嬉しいです。
詳しくはこちら https://twitter.com/japwork
- 投稿日:2020-10-19T17:53:49+09:00
Rails 新規アプリケーション作成の基本
新規アプリケーション作成の基本
今回はruby on railsで新規アプリケーションを立ち上げる際の基本をまとめておこうと思います。
前提としてrailsのバージョンは6.0.0でデータベースはMySQLというツールを用います。
新規アプリの準備
# ディレクトリの移動 % cd ~/アプリを作成したいディレクトリ名 # 新規アプリを作成(chochikuというアプリ名)、-dオプションでMySQLの使用を明示して作成 % rails _6.0.0_ new chochiku -d mysql # 作成したchochikuのディレクトリに移動 % cd chochiku以上のコードをターミナルに打つことで新規アプリケーションが立ち上がります。
データベースの作成
コマンドを利用してアプリのデータベースを作成しますが、その前にデータベースに関する設定を少しする必要があります。
データベースに関する設定はdatabase.ymlに記述します。
database.ymlのdefaultの下のencoding: utf8mb4という記述を
encoding: utf8に変更しますそして以下のコマンドを実行すればデータベースの作成を行います
※必ず自分の作るアプリのディレクトリでコマンドを実行してください!% rails db:createモデルの作成
railsのアプリケーションにはデータベースとやりとりをするモデルが必要になります。
# Expenseモデルを作成 % rails g model expenseテーブルの作成
マイグレーションファイルの編集
上記のモデルを作成した時、同時にマイグレーションファイルがdb/migrateというディレクトリに生成されます。
このマイグレーションファイルを編集してテーブルに保存する情報を決定します。class CreateExpenses < ActiveRecord::Migration[6.0] def change create_table :expenses do |t| t.string :name t.integer :shuppi t.timestamps end end end例えばt.string :nameというコードはstring型でnameというカラムをテーブルに追加しているということです。
マイグレーションの実行
マイグレーションファイルを編集しただけではテーブルについて変更を加えたことにはなりません。そこでマイグレーションの実行をする必要があります。
以下のコマンドを実行することでマイグレーションを実行することができます。% rails db:migrateまとめ
以上でアプリの一つのモデルとそのモデルに紐づくテーブルを作ることができました。
実際にはこれからこのモデルに紐づくコントローラーやルーティング、ビューを作っていくことでアプリを作ることになります。
新規アプリ作成の基本としてはとりあえずここまでですm
- 投稿日:2020-10-19T16:14:14+09:00
保存された状態で同じ画面に遷移したい
【概要】
1.結論
2.どのようにコーディングしたか
3.開発環境
補足
1.結論
redirect_to "/XXXX/#{@@@@@.XXXX.id}"とコーディングする!
2.どのようにコーディングしたか
def create @comment = Comment.new(comment_params) if @comment.valid? @comment.save redirect_to "/reports/#{@comment.report.id}" endreportという投稿に、さらにその投稿にコメントを付け加えることができるアプリです。その際に、reportの投稿にコメントを付け加え終わった後にrootで最初の画面に戻っても良いと思います。しかし、ちゃんとコメントが残っているかの確認も含めてコメントを投稿する画面に戻したいのでこのようなコーディングになりました。
3.開発環境
Mac catalina 10.15.4
Vscode
Ruby 2.6.5
Rails 6.0.3.3
補足
redirect_to report_path(id: current_user) #devise gemを使用。としても一応エラーは起きませんが、current_userなので、1番目に登録したのであれば/reports/1という風になってしまい、2番目に投稿したreportとは違う1番目のreportに戻されるので注意が必要です。
- 投稿日:2020-10-19T15:52:38+09:00
三項演算子について
アプリケーションを作成するにあたり三項演算子について学んだので備忘録として残しておきます。
三項演算子とは
「if ~ else ~」を一文で書きたいときに使う演算子
例) (結果は同じ)
①if〜elseで記述if hoge == 3 "true" else "false" end②三項演算子を利用hoge == 3 ? 'true' : 'false'
条件1 ? 条件1が正しいとき : 条件1が正しくないとき
で使用する便利そうではあるが式が複雑になるとわかりづらくなりそうなため、うまく使い分けることが大切ではないだろうか。
Rubyのリファレンスには条件演算子
で載っておりrailsドキュメントには三項演算子
で載っている。
調べてみたところ違いはなさそう。参考記事
- 投稿日:2020-10-19T13:54:00+09:00
[プログラミング大全] §1はじめてのプログラミング
目的
「プログラミングを学ぼう!!」と意気込んだものの、
プログラミングって難しそうだし、英語も読めないし、PC操作自体苦手だし、
昔に挫折したし、というあなたに向けて、
この記事を読み・PCを動かすだけで「なんだ!プログラミングって面白いじゃん!」
って思ってもらうのが目的です。プログラミング大全というタイトルで連載化していきたいと考えています。
開発環境
- Mac:macOS10.15.7(メインPC)
- ブラウザ:Google Chrome
- テキストエディタ:VSCode(Visual Studio Code)
プログラミングとは?
コンピューターが読むことのできるデータをプログラム、
プログラムを作成、記述していく作業のことをプログラミングと呼ぶ。プログラムを行うときに使用する言語をプログラミング言語と呼ぶ。
プログラミング言語で書かれ、
人間が理解できる状態のテキストやファイルをソースコードと呼ぶ。
*単に「ソース」、「コード」と呼ぶこともある。Rubyとは何か?
Rubyとはプログラミング言語の1つです。
Webアプリケーション作成において使われることが多いです。
→Ruby公式サイト具体的な開発例としては
クックパッド、食べログ、Twitter、huluなどが挙げられます。Rubyの特徴としては、小さなプログラムから大きなアプリまで手軽に作れます。
また、文法が直感的にわかりやすく、日本語の参考記事が多いことから、
「プログラミングってどの言語から学習すればいいの?」
と聞かれたら「Ruby」と答える方がも多いです。プログラミングの流れ
1. プログラムをテキストエディタに記述して保存する。
2. PCに、記述したプログラムを実行する様に命令を出す。ここで重要なのはプログラムは保存して、実行しなければいけないことです。
実行しなければ、ただのメモと同じです。書いたものをPCに読み込ませることで
初めてプログラムが実行されます。ではでは、プログラミングを学んでいく前にPC以外に必要なものを準備していきましょう!
プログラミングに必要なものの準備
ブラウザとテキストエディタを準備しましょう!
Google Chromeのインストール
こちらの公式サイトからインストール。
後々のためにGoogleアカウントを作成することをおすすめします!VSCode(Visual Studio Code)のインストール
こちらの公式サイトからインストール。
この2つのソフトに関しては使用頻度が高いのでインストールが完了したら、
自分が使いやすい位置に配置しておくことをお勧めします。以上です!
今回は座学がメインでしたが、
次回からは、プログラミングに向けて具体的にPCを動かしていきたいと思います。備考
───────────────────────────────
■著者おすすめの本
───────────────────────────────「プロになるためのWeb技術入門」
「転職の思考法」
「ハイパワーマーケティング」
「嫌われる勇気」
「アウトプット大全」───────────────────────────────
■著者おすすめの映画
───────────────────────────────「マイ・インターン」
「シン・ゴジラ」
「ドラゴンボール超 ブロリー」
「School of Roc」
- 投稿日:2020-10-19T10:45:52+09:00
pryでparamsの中身を確認する
背景
記事詳細を表示する際に、ユーザー名を表示したかったが、どこに格納されているのかわからず、paramsの中身を調べることにした。その過程のログを残しておく。
やり方
gemをインストール (gem 'pry-rails')
↓
bundle install
↓
調べたい該当箇所に、binding.pryを入力。
↓
rails s
↓
該当箇所をブラウザでぽちぽち。ターミナルに、入力した箇所で止まったログが表示される。
↓
そして、[1] pry(#)>
と表示されるから、そこに知りたい文字列を入力。qiita.controller.rb12: def show 13: #一つの投稿のみを取得したい。 14: @post = Post.find(params[:id]) => 15: binding.pry 16: end試しに上から順に、
id
params[:id]
@post.content
@post.user
と入力してみた![1] pry(#<PostsController>)> id NameError: undefined local variable or method `id' for #<PostsController:0x00007f9f26ea4828> from (pry):1:in `show' [2] pry(#<PostsController>)> params[:id] => "1" [3] pry(#<PostsController>)> @post.content => "Temporibus vel ratione aperiam alias aut libero reiciendis voluptatem quo autem rerum doloribus adipisci a voluptas modi illo qui ipsum aliquid voluptatum nventore at esse maiores ut omnis accusantium animi ducimus qui autem architecto excepturi itaque ex minus facere soluta inventore molestias id unde vero sunt aliquam quia dolorum quae placeat deserunt aspernatur qui suscipit quod dolorem maxime nulla id molestiae incidunt aut beatae aut voluptate aliquid dicta velit sit sint eum possimus nihil non voluptatem provident enim assumenda consequatur fugiat." [4] pry(#<PostsController>)> @post.user User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]] ↳ (pry):4:in `show' => #<User:0x00007f9f26c77b68 id: 1, name: "swifty_kazu", email: "hogehogehoge", created_at: Fri, 16 Oct 2020 02:53:43 UTC +00:00, updated_at: Fri, 16 Oct 2020 02:53:43 UTC +00:00, password_digest: [FILTERED], admin: true> [5] pry(#<PostsController>)> @post.user.name => "swifty_kazu" [6] pry(#<PostsController>)>exit!で抜け出せる
参考記事
https://qiita.com/tomoharutt/items/6b12af3dc5eb8dfb9801
https://pikawaka.com/rails/params#params%E3%81%AE%E4%B8%AD%E8%BA%AB%E3%82%92%E7%A2%BA%E8%AA%8D%E3%81%97%E3%81%A6%E3%81%BF%E3%82%88%E3%81%86
https://qiita.com/k0kubun/items/b118e9ccaef8707c4d9f
- 投稿日:2020-10-19T09:28:07+09:00
Gem ~ active_model_serializers ~
公式
https://github.com/rails-api/active_model_serializers/tree/v0.10.6/docs
Serializer の作成
be rails g serializer api::v1::articles_preview_serializer作成されたファイル
app/serializers/api/v1/articles_preview_serializers.rb
class Api::V1::ArticlesPreviewSerializer < ActiveModel::Serializer # 出力したい値を指定 attributes :id, :title, :updated_at endid, title, updated_at を出力するよう指定。
コントローラ
app/controllers/api/v1/articles_controllers.rb
module Api::V1 class ArticlesController < BaseApiController def index articles = Article.all.order(updated_at: "DESC") # レスポンスの値が複数の場合、 each_serializer を使用する。 render json: articles, each_serializer: Api::V1::ArticlesPreviewSerializer end end endserializer と同じ階層構造にすること。
作成した article を updated_at 順に昇順にするよう指定。
同階層に base_api_controllers.rb
class Api::V1::BaseApiController < ApplicationController endRequest spec
とりあえずダミーデータを作成して参照する。
spec/requests/api/v1/article_request_spec.rb
require 'rails_helper' RSpec.describe "Api::V1::Articles", type: :request do describe " GET /api/v1/article " do subject { get(api_v1_articles_path) } before { create(:article, updated_at: 3.days.ago ) } before { create(:article) } before { create(:article, updated_at: 1.days.ago ) } it "記事の一覧が取得できる" do subject end end endRequest spec についてはまた後日。
実行結果
[1] pry(#<RSpec::ExampleGroups::ApiV1Articles::GETApiV1Article>)> res = JSON.parse(response.body) => [{"id"=>56, "title"=>"Consequuntur quia corporis perspiciatis.", "updated_at"=>"2020-10-17T22:19:32.120Z"}, {"id"=>57, "title"=>"Molestiae tempore recusandae qui.", "updated_at"=>"2020-10-16T22:19:32.122Z"}, {"id"=>55, "title"=>"Consectetur nam odio voluptatibus.", "updated_at"=>"2020-10-14T22:19:31.192Z"}]UserSerializer の追加
class Api::V1::UserSerializer < ActiveModel::Serializer # 出力したい値を指定 attributes :id, :name, :email endArticlesPreviewSerializer の修正
class Api::V1::ArticlesPreviewSerializer < ActiveModel::Serializer # 出力したい値を指定 attributes :id, :title, :updated_at belongs_to :user, serializer: Api::V1::UserSerializer end実行結果
[1] pry(#<RSpec::ExampleGroups::ApiV1Articles::GETApiV1Article>)> res = JSON.parse(response.body) => [{"id"=>59, "title"=>"Esse facere cum rerum.", "updated_at"=>"2020-10-19T00:06:27.375Z", "user"=>{"id"=>69, "name"=>"Eduardo Kohler Haley", "email"=>"2_janella@renner-dach.org"}}, {"id"=>60, "title"=>"Cumque aut repudiandae numquam.", "updated_at"=>"2020-10-18T00:06:27.377Z", "user"=>{"id"=>70, "name"=>"Collen Stark Brakus", "email"=>"3_hung@wintheiser.org"}}, {"id"=>58, "title"=>"Corporis molestiae dolor odit.", "updated_at"=>"2020-10-16T00:06:26.556Z", "user"=>{"id"=>68, "name"=>"Fr. Pauline Sporer Greenfelder", "email"=>"1_wendy@goldner.net"}}]
- 投稿日:2020-10-19T07:43:50+09:00
CircleCIマン が GitHub Actions を導入するまで
普段は CircleCI でCI/CDを構築していた自分が何もわからない状態から GitHub Actions をどうやって導入したかを紹介しようと思います
自作のRubyのコマンドラインツールにCIを導入した時の話になります
自作のRubyのコマンドラインツールについて
qiita_command という Qiitaのトレンド情報(Daily, Weekly, Monthly)をコマンドラインで簡単に見れるツールです
GitHub Actionsの初回導入
とりあえず簡素な状態でGitHub Actionsが動く状態まで持っていきます
テンプレートの選択
まず始めに Actions をクリックし Ruby の Set up this workflow をクリックします
リポジトリの内容にあったWorkflowsテンプレートを表示してくれるので良さそうなものを選択し導入します
Workflowsのファイルをリポジトリに追加
当たり前だがCircleCIとymlファイルの中身が違う
見てもよくわからない……とりあえず、 RSpecが実行される ように Run tests の部分を変更する
変更前
- name: Run tests run: bundle exec rake変更後
- name: Run tests run: bundle exec rspecリポジトリに .github/workflows 配下にGitHub Actionsのファイルが出来上がることがわかります
最後に Start commit をクリックして Commit new file をクリックしてリポジトリにコミットします
実行結果を確認する
再度、 Actions をクリックし Workflows の一覧から先程作成したWorkflowsのコミットの Create ruby.yml をクリックします
左側の test をクリックし詳細を確認します
CIが実行中の場合です
CIが完了すると以下のような画面になります
以上で簡単に RSpec を実行するだけの CI を実装することができました
workflows ファイルの中身を確認してみる
name、jobs について
name が上に表示され、 jobs の内容が name 配下に表示されます
jobs は複数追加することができますon について
GitHub Actions が実行されるトリガーを設定することができます(いろいろなイベントに対して トリガー を実行できる)
下の例だと main ブランチでpush、pull request が行われた時に実行されるように設定されていますon: push: branches: [ main ] pull_request: branches: [ main ]CircleCIでもブランチによるCIの制御を行うことができるが push や pull request で制御を行うことができない
CircleCIだと以下のようになるworkflows: build-deploy: jobs: - build_server_pdfs: filters: branches: only: mainruns-on について
ここで実行する環境を指定します
ubuntu の最新バージョンになりますruns-on: ubuntu-latestCircleCIで言うところの下記のような記述の一部と同じになります
GithubAcitonsではOS寄りな環境設定になりますが CircleCI では言語に寄っていることが多い気がします
Docker Image の circleci/ruby:2.6.0 が何で作られているかによってOSが決まりますexecutors: base: docker: - image: circleci/ruby:2.6.0uses について
uses を使用することにより、再利用可能なコードを宣言することができる
with を使用して設定を追加することができる
- actions/checkout@v2はリポジトリをチェックアウトしてくれる
- ruby/setup-rubyはビルド済みのRubyをダウンロードしPATHに追加して Ruby を使えるようにしてくれる
steps: - uses: actions/checkout@v2 - name: Set up Ruby uses: ruby/setup-ruby@ec106b438a1ff6ff109590de34ddc62c540232e0 with: ruby-version: 2.6CircleCI で言うところの CircleCI Orbs に近い気がします
orbs: slack: circleci/slack@3.4.2 ・ ・ ・ workflows: version: 2.1 main: jobs: - slack/approval-notification: message: ':circleci-pass: Slackへメッセージを送付します'run について
これは CircleCI と同じでコマンドを実行できます
- name: Install dependencies run: bundle install - name: Run tests run: bundle exec rspecコマンドの実行履歴で name で設定した部分が GitHub Actions に表示されます
自分の思い通りにGitHub Actionsを設定する
とりあえずGitHub Actionsというものを雰囲気分かってもらえたと思います
最小構成で実装することができたが他のプロジェクトではどのように設定しているのだろうか……先人の知恵をお借りする
BestGems.org という Ruby gems のダウンロードランキングを確認することができるサイトから総ダウンロード数TOP10のプロジェクトを参考にしてみたいと思います
ランキング 名前 GitHub Actions使用有無 1 rspec-expectations ❌ 2 rspec-core ❌ 3 rspec-mocks ❌ 4 diff-lcs ⭕ 5 rspec-support ❌ 6 rspec ❌ 7 bundler ⭕ 8 multi_json ❌ 9 rack ⭕ 10 rake ⭕ ※ランキングは 2020年10月16日のものです
diff-lcs、bundler、rack、rake を参考にして作成していきたいと思います
ファイル構成を確認する
プロジェクトごとファイル構成を確認する
diff-lcs
ci.yml は複数のOS、複数のRubyのバージョンでのテストを実行しているようだ
diff-lcs └ .github └ workflows └ ci.ymlbundler
主にテストをOSごと実行する Workflow に Linter を実行する Workflow に分けているようだ
bundler └ .github └ workflows ├ jruby.yml ├ ubuntu-bundler3.yml ├ ubuntu-lint.yml ├ ubuntu.yml └ windows.ymlrack
development.yml は複数のOS、複数のRubyのバージョンでのテストを実行しているようだ
rack └ .github └ workflows └ development.ymlrake
主にテストをOSごと、複数のRubyバージョンでのテストを実行しているようだ
rake └ .github └ workflows ├ macos.yml ├ test.yml └ windows.ymlファイルの中身を参考にする
ファイルの中身を確認し参考になりそうな部分を確認してみる
rake/.github/workflows/test.yml
下記のようにすると
runs-on: ${{ matrix.os }} strategy: matrix: os: [ 'ubuntu-latest', 'macos-latest', 'windows-latest' ] ruby: [ 2.6, 2.5, 2.4, 2.3, 2.2, jruby, jruby-head, truffleruby, ruby-head ] ・ ・ ・ steps: - uses: ruby/setup-ruby@v1 with: ruby-version: ${{ matrix.ruby }}OSとRubyのバージョンを配列で宣言して1つのファイルでCIを実行することができるようだ
name: ubuntu on: [push, pull_request] jobs: build: runs-on: ${{ matrix.os }} strategy: matrix: os: [ 'ubuntu-latest', 'macos-latest', 'windows-latest' ] ruby: [ 2.6, 2.5, 2.4, 2.3, 2.2, jruby, jruby-head, truffleruby, ruby-head ] exclude: - os: windows-latest ruby: truffleruby - os: windows-latest ruby: jruby-head - os: windows-latest ruby: jruby steps: - uses: actions/checkout@v2 - uses: ruby/setup-ruby@v1 with: ruby-version: ${{ matrix.ruby }} - name: Install dependencies run: gem install minitest - name: Run test run: ruby -Ilib exe/rakediff-lcs/.github/workflows/ci.yml
下記のようにすると
runs-on: ${{ matrix.os }}-latestruns-onの指定の時 -latest で宣言するとOSの指定をOS名だけで宣言することができるらしい
つまりOS名とバージョンの指定を分離することができる# This workflow uses actions that are not certified by GitHub. # They are provided by a third-party and are governed by # separate terms of service, privacy policy, and support # documentation. # This workflow will download a prebuilt Ruby version, install dependencies and run tests with Rake # For more information see: https://github.com/marketplace/actions/setup-ruby-jruby-and-truffleruby name: CI on: push: branches: [ master ] pull_request: branches: [ master ] jobs: test: strategy: matrix: os: - ubuntu - macos - windows ruby: - 2.5 - 2.6 - 2.7 - head - debug - mingw - mswin - jruby - jruby-head - truffleruby - truffleruby-head exclude: - os: macos ruby: mingw - os: macos ruby: mswin - os: ubuntu ruby: mingw - os: ubuntu ruby: mswin - os: windows ruby: debug - os: windows ruby: truffleruby - os: windows ruby: truffleruby-head runs-on: ${{ matrix.os }}-latest continue-on-error: ${{ endsWith(matrix.ruby, 'head') || matrix.ruby == 'debug' || matrix.os == 'windows' }} steps: - uses: actions/checkout@v2 - name: Set up Ruby uses: ruby/setup-ruby@v1 with: ruby-version: ${{ matrix.ruby }} bundler-cache: true - name: Install dependencies run: bundle install - name: Run tests run: bundle exec ruby -S rakeworkflows のファイルを編集する
上記情報を元にファイルを編集していく
複数OS、複数Rubyバージョンで実行できるようにする
- workflows 名を CI に変更
- OSを ubuntu、macos で実行できるようにする
- Rubyのバージョンを 2.7、2.6 で実行できるようにする
- uses で使用している ruby/setup-ruby のバージョンを v1 にする
name: CI on: push: branches: [ main ] pull_request: branches: [ main ] jobs: ci: strategy: matrix: os: [ubuntu, macos] ruby: [2.7, 2.6] runs-on: ${{ matrix.os }}-latest steps: - uses: actions/checkout@v2 - name: Set up Ruby uses: ruby/setup-ruby@v1 with: ruby-version: ${{ matrix.ruby }} - name: Install dependencies run: bundle install - name: Run tests run: bundle exec rspecブランチでの絞り込みをなくす
- push と pull_request のイベント時に実行されるよう on 句を変更する
on: [push, pull_request]
on句を上記の書き方に変更する
name: CI on: [push, pull_request] jobs: ci: strategy: matrix: os: [ubuntu, macos] ruby: [2.7, 2.6] runs-on: ${{ matrix.os }}-latest steps: - uses: actions/checkout@v2 - name: Set up Ruby uses: ruby/setup-ruby@v1 with: ruby-version: ${{ matrix.ruby }} - name: Install dependencies run: bundle install - name: Run tests run: bundle exec rspec
静的解析ツールを実行する
- RuboCopが実行されるようにする
- name: Run Rubocop run: bundle exec rubocop
上記設定を追加する
name: CI on: [push, pull_request] jobs: ci: strategy: matrix: os: [ubuntu, macos] ruby: [2.7, 2.6] runs-on: ${{ matrix.os }}-latest steps: - uses: actions/checkout@v2 - name: Set up Ruby uses: ruby/setup-ruby@v1 with: ruby-version: ${{ matrix.ruby }} - name: Install dependencies run: bundle install - name: Run Rubocop run: bundle exec rubocop - name: Run tests run: bundle exec rspec
テストのカバレッジ結果を見れるようにする
CircleCIだと store_artifacts を使用するとアーティファクトのアップロードができるようになります
同じことをGitHub Actionsでもできるようにします
公式のドキュメントの以下の記事を参考にテストのカバレッジをアーティファクトとしてアップロードされるようにしようと思います記事を参考に下記の設定を追加します
- name: Archive code coverage results uses: actions/upload-artifact@v2 with: name: code-coverage-report path: coverage
設定追加後
name: CI on: [push, pull_request] jobs: ci: strategy: matrix: os: [ubuntu, macos] ruby: [2.7, 2.6] runs-on: ${{ matrix.os }}-latest steps: - uses: actions/checkout@v2 - name: Set up Ruby uses: ruby/setup-ruby@v1 with: ruby-version: ${{ matrix.ruby }} - name: Install dependencies run: bundle install - name: Run Rubocop run: bundle exec rubocop - name: Run tests run: bundle exec rspec - name: Archive code coverage results uses: actions/upload-artifact@v2 with: name: code-coverage-report path: coverage
Slack通知を実装する
CircleCI の場合は Orb を使用することでSlack通知を行うことができるようになる
GitHub Actionsでは同じように uses を使用して行うことができるようだ
幾つかSlack通知が行えるものがあるようだが今回はドキュメントもしっかりとある action-slack を使用して実装するドキュメントを参考に以下を追加する
- name: Github Actions notify to Slack uses: 8398a7/action-slack@v3 with: status: ${{ job.status }} fields: repo,message,commit,author,action,eventName,ref,workflow,job,took mention: 'here' if_mention: failure env: GITHUB_TOKEN: ${{ github.token }} SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} MATRIX_CONTEXT: ${{ toJson(matrix) }} if: always()
このままでは以下の部分が設定されてないので読み取ることができないsecrets.SLACK_WEBHOOK_URL
以下の公式の記事を参考にSlackの WEBHOOK_URL をリポジトリに設定します
CircleCI の環境変数を設定することと同じことをしています下記の画面みたいな表示になっていれば SLACK_WEBHOOK_URL 設定は大丈夫です
上記設定が完了したら設定を追加します
name: ci on: [push, pull_request] jobs: ci: strategy: matrix: os: [ubuntu, macos] ruby: [2.7, 2.6] runs-on: ${{ matrix.os }}-latest steps: - uses: actions/checkout@v2 - name: set up ruby uses: ruby/setup-ruby@v1 with: ruby-version: ${{ matrix.ruby }} - name: install dependencies run: bundle install - name: run rubocop run: bundle exec rubocop - name: run tests run: bundle exec rspec - name: archive code coverage results uses: actions/upload-artifact@v2 with: name: code-coverage-report path: coverage - name: github actions notify to slack uses: 8398a7/action-slack@v3 with: status: ${{ job.status }} fields: repo,message,commit,author,action,eventname,ref,workflow,job,took mention: 'here' if_mention: failure env: github_token: ${{ github.token }} slack_webhook_url: ${{ secrets.slack_webhook_url }} matrix_context: ${{ tojson(matrix) }} if: always()
実際に実行する
上記で編集した workflows のファイルを push することで GitHub Actions が実行されるようになります
詳細を確認していく
OS、RubyのバージョンごとCIが実行されるようになっています
完了すると Artifacts にテストのカバレッジ結果が zip で圧縮されてダウンロードできるようになっています
CircleCIと違って画面から結果を確認することはできませんまた1つのCIが完了するごとにSlackに完了通知が飛びます
これで一通りやりたかったことができるようになりました!
応用編:Gemの自動アップデート用のプルリクをGitHub Actionsで自動化する
応用編として、Gemの自動アップデート用のプルリクを自動で作成する workflows を作ろうと思います
SSH で GitHub Actions に入る
CIを作成していく段階で個人的に必須な SSH で接続する機能は CircleCI では当たり前だが GitHub Actions ではどうするのか……
公式では用意されていないようなので uses を使用して行うことができる
下記の記事を参考にするとよいスケジュールで実行するにはどうしたよいのか?
CircleCI だとトリガーを使用することでスケジュールされたCIを実行することができる
GitHub Actions では on.schedule を使用することで実現できそうですCircleCI でも GitHub Actions のどちらも cron 形式でスケジュールを設定することができます
crontab guru のサイトを参考にしてスケジュールを設定するとよいでしょうこんな感じで設定する
on: schedule: # * はYAMLに置ける特殊文字なので、この文字列は引用符で囲まなければならない - cron: '*/15 * * * *'schedule の詳しい仕様については公式のドキュメントを参考にすること
CircleCI と同じで GitHub Actions も cron は UTC で設定する必要があります
手順を考える
以下の手順をCIで実行することができれば実現できそうである
- ① Gitの設定を行う(メールアドレス、ユーザー名)
- ② Gem Update 用のブランチを作成する
- ③ bundle update を行う
- ④ commit して push する
- ⑤ プルリクエストを自動で作成する
- ⑥ Slackに完了通知を行う
実装する
上記で考えた手順を元に実際に実装していく
手順以外の実装
毎月の1日の9時に実行されるようにする
cron 式で設定した以外は先程、作成したものとほぼ同じである
設定内容
name: GemUpdate on: schedule: - cron: '0 0 1 * *' jobs: create-gem-update: strategy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Set up Ruby uses: ruby/setup-ruby@v1 with: ruby-version: 2.7 - name: Install dependencies run: bundle install
① Gitの設定を行う(メールアドレス、ユーザー名)
git checkout ができているので git はおそらくインストールされている前提ですすめる
インストールされているかなど調査する時は直接 ssh で接続して確認すると良い複数行の時はCircleCIと同じく | を使用するようだ
- name: Settings Git run: | git config --global user.email ${{ secrets.MAIL_ADDRESS }} git config --global user.name "dodonki1223"secrets.MAIL_ADDRESS こちらの設定は SLACK_WEBHOOK_URL と同じように設定します
この場合はメールアドレス直打ちでもいいような気がする② Gem Update 用のブランチを作成する
ブランチを名前を付けて切り替えるコマンドです
gem_update_20201001 みたいな形がブランチ名になりますgit checkout -b "gem_update_`date +%Y%m%d`"③ bundle update を行う
前の段階で bundle install を行っているので update を行うだけです
bundle update④ commit して push する
ファイルをコミットして先程作成したブランチに push します
git add . git commit -m ':wrench: Gem Update' git push origin "gem_update_`date +%Y%m%d`"⑤ プルリクエストを自動で作成する
hubコマンドを使用してプルリクエストを作成する
最近、GitHub CLI がリリースされたので hubコマンドの代わりに GitHub CLI を使用するでもよいかもしれませんhub pull-request -b master -m "? Gem Update `date +%Y-%m-%d`"②〜⑤を組み立てる
基本的には②〜⑤をそのまま繋げるだけで大丈夫なのですが下記の記述が追加で必要です
env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}上記記述に関しては hubコマンドのリポジトリに Readme に GitHub Actions で使用する時のサンプル例に書かれている例になります
- name: Create gem update pull request run: | git checkout -b "gem_update_`date +%Y%m%d`" bundle update git add . git commit -m ':wrench: Gem Update' git push origin "gem_update_`date +%Y%m%d`" hub pull-request -b master -m "? Gem Update `date +%Y-%m-%d`" env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}コマンドを組み上げる時は基本的には実際に ssh でログインして実際の環境で使用できるか確認しながらすすめるとよいです
コマンドのインストールが必要かどうかなども ssh でログインしながら確かめると良いです⑥ Slackに完了通知を行う
こちらは先程、作成したもので既に行っているので特に説明はしません
- name: Github Actions notify to Slack uses: 8398a7/action-slack@v3 with: status: ${{ job.status }} fields: repo,message,commit,author,action,eventName,ref,workflow,job,took mention: 'here' if_mention: failure env: GITHUB_TOKEN: ${{ github.token }} SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} if: always()完成品
実際に作成したもので最終形は以下になります
完成品
name: GemUpdate on: schedule: - cron: '0 0 1 * *' jobs: create-gem-update: strategy: runs-on: ubuntu-latest steps: - uses: actions/checkout@v2 - name: Set up Ruby uses: ruby/setup-ruby@v1 with: ruby-version: 2.7 - name: Install dependencies run: bundle install - name: Settings Git run: | git config --global user.email ${{ secrets.MAIL_ADDRESS }} git config --global user.name "dodonki1223" - name: Create gem update pull request run: | git checkout -b "gem_update_`date +%Y%m%d`" bundle update git add . git commit -m ':wrench: Gem Update' git push origin "gem_update_`date +%Y%m%d`" hub pull-request -b master -m "? Gem Update `date +%Y-%m-%d`" env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Github Actions notify to Slack uses: 8398a7/action-slack@v3 with: status: ${{ job.status }} fields: repo,message,commit,author,action,eventName,ref,workflow,job,took mention: 'here' if_mention: failure env: GITHUB_TOKEN: ${{ github.token }} SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }} if: always()
注意事項
on.schedule は下記の時だけ実行されます
デフォルトまたはベースブランチの直近のコミットで実行されます
これに気づかないといくらやってもスケジュールが実行されずハマることになります……自分は実行されずにすごく困ったらこれが原因でした
CircleCIとGitHub Actions の違うところ
自分が感じた CircleCI と GitHub Actions の違いをまとめようと思います
GitHub Actionsは遅い時がある
GitHub Actionsを使っていて気になったのだがなぜかすごく遅い時がある
CircleCIだとだいたい終了時間が同じ感覚を受けるがGitHub Actionsはやたらと遅い時がある使用されるサーバーのスペックガチャにより早かったり、遅かったりするのかも知れない……
いろいろなトリガーが用意されている
CircleCI と違っていろいろな webhookイベントをトリガーに実行できるようだ
詳しくはドキュメントを参考にすると良いファイルの構成がスッキリする
CircleCIと違ってファイルの分割ができるため、行数を少なくすることができる
最後に
ずっとGitHub Actionsが難しそうで逃げていましたが実際にやってみるとすぐに実装することができました
先人の知恵をお借りしたことにより自分の中で思ったよりも早く理解することができたのだと思いますこれからもGitHub Actions を使っていきましょう!!
- 投稿日:2020-10-19T02:24:51+09:00
消し損ねたマイグレーションファイルを完全に消す
謎のマイグレーションファイルがあって気持ち悪いので消し方を調べてスッキリしたことを書いていこうと思います。
現在のマイグレーションファイルの状況
rails db:migrate:statusマイグレーションファイルを確かに消したはずなのに
こんな感じでNO FILEが残ってる。
NO FILEはマイグレーションファイルは消したはずなのにコンピューター上に残ってしまっているということです。気持ち悪いので消します。
rails db:rollback
- これでstatusの部分がupからdownになります。(編集できるということ)
- この空のファイルを名前をつけて復活させる
touchコマンド
touch db/migrate/20200929050736_hoge.rb
これによってhogeというマイグレーションファイルが復活します。しかしこのファイルには何も書かれていないので適当に記述します。以下の文を丸々追加class Hoge < ActiveRecord::Migration[6.0] def change end endrails db:migrateを実行する
rails db:migrateここまできたら消す準備OK。しかしステータスがupのままなので消すためにはdownにする必要がある。
rails db:rollbackdownになりました。ここで消すコマンド
rm -rf db/migrate/20200929050736_Hoge.rbもう一度rails db:migrate:statusで確認してみましょう
これで消し損ねたファイルを完全に消すことができました。
- 投稿日:2020-10-19T00:28:29+09:00
オフライン環境構築 Ruby編
- 投稿日:2020-10-19T00:11:05+09:00
画像をぼかす方法(超簡単)
- 投稿日:2020-10-19T00:04:01+09:00
【RSpec】mailer(パスワードのリセット処理)のテストを書いたときにはまった点
最近RSpecにも割と慣れてきて油断しているところに、見たこともないエラーが出てきて少し詰まったのでここで共有したいと思います。
リクエストスペックでmailer(パスワードのリセット処理)のテストを書いたときの話です!エラー内容
Failure/Error: expect(mail.body.encoded).to match user.reset_token expected "\r\n----==_mimepart_5b18de57c36e0_75293fd69de666b8448c9\r\nContent-Type: text/plain;\r\n charset=UTF...\nL2E+CgogIDwvYm9keT4KPC9odG1sPgo=\r\n\r\n----==_mimepart_5b18de57c36e0_75293fd69de666b8448c9--\r\n" to match "HAY" Diff: @@ -1,2 +1,32 @@ -HAY + +----==_mimepart_5b18de57c36e0_75293fd69de666b8448c9 +Content-Type: text/plain; + charset=UTF-8 +Content-Transfer-Encoding: base64 + +SEFZCuOBggoK + +----==_mimepart_5b18de57c36e0_75293fd69de666b8448c9 +Content-Type: text/html; + charset=UTF-8 +Content-Transfer-Encoding: base64 + +PCFET0NUWVBFIGh0bWw+CjxodG1sPgogIDxoZWFkPgogICAgPG1ldGEgaHR0 (省略) +L2E+CgogIDwvYm9keT4KPC9odG1sPgo= + +----==_mimepart_5b18de57c36e0_75293fd69de666b8448c9--こんな感じのエラーが出てきました。
どうやらRSpecでメール本文のエンコード処理が正しくできていないせいで、期待している値と一致せずにテストに失敗しているようです。解決策
パスワードのリセットトークンを作る時、Base64を使ってエンコードしているので、それを元に戻して比較するとうまくいきました。(デコード)
password_resets_request_spec.rbRSpec.describe UserMailer, type: :mailer do let(:user) { FactoryBot.create(:user, email: 'mailer_tester@example.com') } describe "パスワードリセット処理" do let(:mail) { UserMailer.password_reset(user) } # Base64 encodeをデコードして比較できるようにする let(:mail_body) { mail.body.encoded.split(/\r\n/).map{|i| Base64.decode64(i)}.join } it "ヘッダーが正しく表示されること" do user.reset_token = User.new_token expect(mail.to).to eq ["mailer_tester@example.com"] expect(mail.from).to eq ["noreply@protuku.com"] expect(mail.subject).to eq "パスワードの再設定" end # メールプレビューのテスト it "メール文が正しく表示されること" do user.reset_token = User.new_token expect(mail_body).to match user.reset_token expect(mail_body).to match CGI.escape(user.email) end end end最後まで読んでいただきありがとうございます!
実は、この情報にたどり着くのに少し手間取ったため、記事にしました。
同じようなところで困っている方のお力になれれば幸いです!
ご指摘などあればコメントいただけますと嬉しいです。