- 投稿日:2019-08-04T23:32:51+09:00
RubyのRailsをMySQLでHerokuにあげてみた
今までの麻雀アプリは一人でずっとやるだけだったので、
もう少しデータ的なのを集められるようになりたいなーと思って
ちょっと改良しました。https://rubymahjong.herokuapp.com/
みんなのあがり回数とあがりまでの平均ツモ数を表示できるようにしました!
◇開発言語
ruby 2.6.3
◇サーバーサイドフレームワーク
ruby on rails 5.2.3
◇フロントエンドフレームワーク
Vue.js
◇データベース
MySQL
◇開発OS
mac
◇IDE
vscode
◇ソース管理
GitHub
◇アプリケーションプラットフォーム
Heroku忘れないうちにRuby On Railsのインストール手順とかまとめておきます。
Ruby On Railsのインストール
まぁ、Railsのインストール手順とかは色々記事があるのでそれを見ればできます。
自分はRails Girls ガイドを見ながら環境を作りました。(Girlじゃないけど)基本的にはRails Girls ガイドの通りに作業を進めればいいんですが、
Homebrewのインストールがうまく行きませんでした。
brew doctor を実行してエラーがないか確認したところ11:05:46 Users $ brew doctor Please note that these warnings are just used to help the Homebrew maintainers with debugging if you file an issue. If everything you use Homebrew for is working fine: please don't worry or file an issue; just ignore this. Thanks! Warning: "config" scripts exist outside your system or Homebrew directories. `./configure` scripts often look for *-config scripts to determine if software packages are installed, and which additional flags to use when compiling and linking. Having additional scripts in your path can confuse software installed via Homebrew if the config script overrides a system or Homebrew-provided script of the same name. We found the following "config" scripts: /Library/Frameworks/Python.framework/Versions/3.7/bin/python3.7-config /Library/Frameworks/Python.framework/Versions/3.7/bin/python3.7m-config /Library/Frameworks/Python.framework/Versions/3.7/bin/python3-config 11:05:52 Users $と大量のWarningが…。
原因ですが、「-config」ファイルにPathが通っているとWarningが発生するみたいです。
envコマンドで環境設定確認すると、確かにPythonのPathが通ってますね。11:12:40 Users $ env | grep PATH PATH=/Users/itoutoshiya/.rbenv/shims:/Library/Frameworks/Python.framework/Versions/3.7/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin以下のサイトを参考に、
PathからPythonを除外してbrewコマンドを実行するエイリアスを作成しました。
参考:https://www.task-notes.com/entry/20141223/1419324649alias brew="env PATH=${PATH/\/Library\/Frameworks\/Python.framework\/Versions\/3.7\/bin:/} brew"コンソールを再起動してbrew doctorを再実行。
11:22:47 ~ $ brew doctor Your system is ready to brew.これでHomebrewのインストールはうまくできました!
残りのソフトは、Rails Girls ガイドの通りに実装できました。
MySQLのインストール
MySQLのインストール手順も参考になる記事はたくさんありますね。
自分は以下のサイトが分かりやすかったので参考にさせてもらいました。
https://qiita.com/fuku_tech/items/a380ebb1fd156c14c25bbrew install mysqlrailsプロジェクト作成
必要なものは全部インストールできたので、早速
mysqlを利用するRailsプロジェクトを作成します。
といっても、さすがRails。コマンド一つだけですぐにできます。rails new ./ -d mysql適当なフォルダにて上記コマンドを実行すればOKです。
VScodeにてコンソールを表示し、上記コマンドを実行すれば必要なファイルが勝手に作成されます。config/database.ymlを確認すると、ちゃんとMySQLを使う設定になってますね!
んで、早速Railsの起動コマンド「rails server」を実行。
デフォルトだと地球儀の絵がTOPページに表示されるはず。
うーん失敗。ただ、以下のメッセージからするに、mysqlに接続できていない感じ。
Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)というか、そもそもsqlサーバーを起動していないので、そりゃDB接続できないよってエラー出ますよね。
ということで、以下コマンドを実行してsqlサーバーを起動。mysql.server startうん。sqlサーバーは起動できたみたいです。
じゃぁもう一度Railsを起動し画面を確認!
まぁ、エラーになるよね。今回のエラー原因は以下の通り。Unknown database 'project_development'project_developmentってデータベースがないよーってい言ってますね。
project_developmentは、config/database.ymlで設定している
データベースですね。
mySqlにログインしようとしてもproject_developmentはないからエラーになりますね。
まぁ、project_developmentを作ってないので当たり前ですね。なので、project_developmentを作ります。
ただ、これもRailsを利用して作成することができます。
以下コマンドを実行するだけ!rails db:createはい!できましたー。
じゃぁもう一度Railsを起動し画面を確認!地球の絵!
見慣れた画像が表示されました!
とりあえず、これで環境面は一通りできました!テーブル作成
今回は、上がりまでにかかった自摸の回数をテーブルに記録させていきたいと思います。
Railsのコマンドを実行すると、テーブルやそのテーブルにアクセスするための機能(プログラムファイル)
も自動でできます。rails generate scaffold WonCount name:string wonCount:integerですが、上記コマンドだけだと肝心のテーブル自身は作成されません。
マイグレーションを実行する必要があります。
と言っても難しいことは何もしません。
以下コマンドを実行するだけです。rails db:migrate参考:https://www.sejuku.net/blog/14229
ここまでくれば、後はあがりまでの自摸数をDBに登録するAPIを実装するだけです。
Herokuへのデプロイ
ローカル環境ではうまく出来たので、早速インターネットに公開したいと思います。
サーバーは、またHerokuを使います。便利ですね、PaaS。
参考:http://arfyasu.hatenablog.com/entry/2016/01/11/035101
https://devcenter.heroku.com/articles/rails4#logging-and-assetsrails_12factor
rails_12factorというのをHeroku上で利用できるように設定します。
rails_12factorは、Herokuでのログを見れるようにするgem(Rubyのライブラリ)です。
Gemfileに以下記述を追加するだけでOKです。group :production do gem 'rails_12factor' endProcfile作成
Procfileを作成し、Heroku上での起動コマンドを記述します。
以下記述だけでOK。web: bundle exec rails server -p $PORTHerokuにアップ
はい。ここまで出来たらHerokuにアップします。
HerokuGitにアップする方法もありますが、
自身のGitHubにアップしたプロジェクトを利用します。んで、プロジェクトアップロード後にWebサイトを確認。
はい。失敗〜。
Herokuのログを見ます。コマンドプロンプトから以下コマンドを実行〜。heroku logs --tail --app rubymahjong※「rubymahjong」は、Herokuにアップしたプロジェクト名です。
Mysql2::Error::ConnectionError (Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)):MySQLに接続出来なくてエラーになってますね。
HerokuにMySQLのDB作成
MySQLを利用するにはHerokuにクレジットカードの情報を登録する必要があります。
クレジットカードの登録だけなら無料です。(2019/08/04現在)クレジットカード登録後、コマンドプロンプトから以下コマンドを実行しMySQLが利用できるようにcleardbアドオンをインストールします。
参考:https://www.yuta-u.com/programing/rails/heroku-mysql-2heroku addons:create cleardb:ignite --app rubymahjongHeroku上の「Overview」を見ると、MySQLがアドオンされたことが分かりますね。
以下コマンドを実行してコンフィグを確認しても、MySQLが追加されたことが分かります。
heroku config --app rubymahjongCLEARDB_DATABASE_URLに、デプロイ用のDB接続情報が記載されています。
CLEARDB_DATABASE_URL: mysql://bfc76098d1b006:90049602@us-cdbr-iron-east-02.cleardb.net/heroku_c287fee3253ccb2?reconnect=trueこの情報をDATABASE_URLとして設定します。
ただし、Railsのgemでインストールしているのがmysql2のため、
mysqlではなくmysql2に変更して設定します。heroku config:set DATABASE_URL=mysql2://bfc76098d1b006:90049602@us-cdbr-iron-east-02.cleardb.net/heroku_c287fee3253ccb2?reconnect=true --app rubymahjong変更後、またコンフィグを確認してみます。
【変更後】
heroku config --app rubymahjong
DATABASE_URLが追加されてますね!ActiveRecord::StatementInvalid (Mysql2::Error: Table 'heroku_c287fee3253ccb2.won_counts' doesn't exist: SHOW FULL FIELDS FROM `won_counts`):won_countsテーブルがなくてエラーになってますね。
テーブル作成はマイグレーションですね。以下コマンドを実行!
heroku run rails db:migrate --app rubymahjongなんか出来てる感じですね!
早速ブラウザから画面を確認してみます。
できました!
きちんとあがり回数をDBに登録し、その結果を出力出来てます!Herokuって便利ですねー。
Rails+MySQLってかなりのWebサービスで利用されてそうで、
その環境が簡単に作れると色々なことが出来て夢が広がりますね!
今回のプログラムは以下GitHubにあげてます。
https://github.com/kph7m/rubymahjong
- 投稿日:2019-08-04T23:04:08+09:00
Railsで本番サバーからDemoサバーにデータをコピーする
Railsで本番サバーからDemoサバーにデータをコピーする (rake task)
今Railsプロジェクトを開発している、その時は本番サバーはドンドン新しいデータが登録している。そして同じデータをテストしたい時難しいと思います。したのコート使ってTerminalからデータをコピーができる。
# lib/tasks/db_pull.rake namespace :db do desc 'Pull production db to development' task :pull => [:dump, :restore] task :dump do dumpfile = "#{Rails.root}/tmp/latest.dump" production = Rails.application.config.database_configuration['production'] puts 'mysqldump on production database...' system "ssh user@server.tld 'mysqldump -u #{production['username']} --password=#{production['password']} -h #{production['host']} --add-drop-table --skip-lock-tables --verbose #{production['database']}' > #{dumpfile}" puts 'Done!' end task :restore do dev = Rails.application.config.database_configuration['development'] abort 'Live db is not mysql' unless dev['adapter'] =~ /mysql/ abort 'Missing live db config' if dev.blank? dumpfile = "#{Rails.root}/tmp/latest.dump" puts 'importing production database to development database...' system "mysql -h #{dev['host']} -u root #{dev['database']} < #{dumpfile}" puts 'Done!' end endrake db:pullReference: https://martinschurig.com/posts/2015/02/pulling-production-database-to-local-machine-rails-task/
- 投稿日:2019-08-04T21:42:34+09:00
UnicornがResource temporarily unavailableを吐いたらbacklogの値を確認してみる
背景
railsアプリケーションをnginx+unicornで稼働させている際、以下のエラーが発生していました。
nginxとunicorn間は、UNIXソケットで通信しています。nginx.logconnect() to unix:/tmp/unicorn.sock failed (11: Resource temporarily unavailable) while connecting to upstreamこの時の事象としては、UNIXソケットへの接続がbacklogの値(接続キューのサイズ)を超えてしまったため発生していました。
AmazonLinuxですと、最大接続数の上限はデフォルトだと128となっていました。
ssコマンドで、各ソケットのbacklogの値を確認できます。$ ss -ax | grep -e unicorn u_str LISTEN 0 128 /tmp/unicorn.sock 38120 * 0$ sysctl net.core.somaxconn net.core.somaxconn = 128対応内容
OSのbacklogの上限変更を行います。
以下のコマンドで変更可能ですが、再起動で元に戻ってしまいます。$ sudo sysctl -w net.core.somaxconn=256 net.core.somaxconn = 256
/etc/sysctl.confに追記すると起動の都度反映されるようになります。/etc/sysctl.confnet.core.somaxconn = 256railsアプリケーション上での設定は、listenする際に指定可能です。
config/unicorn.rbに指定した値は、OSでの上限より大きくはなりません。config/unicorn.rblisten "/tmp/unicorn.sock", backlog: 256unicornを再起動すると、以下のようにbacklogの値が変更されていることを確認できます。
$ ss -ax | grep -e unicorn u_str LISTEN 0 256 /tmp/unicorn.sock 38120 * 0
- 投稿日:2019-08-04T20:38:05+09:00
rails webpacker:install実行時にrun() in thread failed: inotify event queue has overflowed
現象
rails webpacker:installを実行するとrun() in thread failed: inotify event queue has overflowedと表示される。
環境
docker-composeでruby:2.6.3をベースに構築。
対応
方法その1.Dockerの設定を変更する。
環境設定→AdvancedのCPUs,Memory,Swapの値を増加する。
方法その2.コンテナ内のファイル以下の記述を追加しsysctl設定にロードする。
/etc/sysctl.conffs.inotify.max_user_watches = 999999 fs.inotify.max_queued_events = 999999 fs.inotify.max_user_instances = 999999以下のコマンドを実行
sudo sysctl -p実行結果確認
cat /proc/sys/fs/inotify/max_user_watches #=> 999999 cat /proc/sys/fs/inotify/max_user_instances #=> 999999 cat /proc/sys/fs/inotify/max_user_watches #=> 999999補足:以下のエラーが表示される場合、privilegedでコンテナを起動する必要がある。
sysctl: setting key "fs.inotify.max_user_watches": Read-only file systemprivilegedを以下の通り記載してコンテナを起動し、再度コンテナ内でsudo sysctl -pを実行する。
docker-compose.ymlversion: '3' services: web: privileged: true結果
rails generate react:installでエラーが出なくなる。エラーによってどういう影響があるかわからないがエラーはない方がいいはず。
参考にさせていただいたサイト
https://github.com/guard/listen/wiki/Increasing-the-amount-of-inotify-watchers
https://github.com/guard/rb-inotify/issues/61
https://qiita.com/osamunmun/items/1786aac5904439522d72
https://wadap.hatenablog.com/entry/20100123/1264211202
- 投稿日:2019-08-04T20:24:32+09:00
『レストラン検索アプリ』の制作過程
はじめに
今回自作アプリを作るのでその過程を残しておきます。(備忘録)
現在制作中なので随時更新されていきます。目次
※別記事をアップしたら随時更新していきます
アプリ概要
●使用する技術
今回はRails+mysql+heroku+bootstrapでアプリを作っていきます。
AWSと迷いましたが、チーム開発でAWSを触っていたので省略してherokuを使います。
もし時間があれば、AWSに移すかもしれません。●解決したい事とアプリへの想い
アプリを作ったキッカケは、ミシュランや食べログなど様々な観点の評価軸をもつサイトがあるが、200店舗程実際に食べてみて、どれも当てにならないと思っていました。(勿論個人の好みもあります)
いつもレストランに行ってトライアンドエラーを繰り返す中で、一番信用出来る情報源は、食通や料理人が美味しいと言うお店だと思いました。
なので私が知っている限りですが、それを紹介できるアプリを作ろうと思ったのがきっかけです。
しかし問題として、私自身美味しいお店を広めたくありません!過去好きなお店が突然点数アルゴリズムが変わったとか
なんとかで、予約が取れなくなる苦い経験を何度かしています。(お店側も結構似た想い持ってるところが多いです、、、)
なので、今回は質問に答えて、それに当てはまる1店舗だけを紹介するという形にしました。拘りも出せて一石二鳥です。
●実装内容
内容としては
・DBにレストラン情報と別テーブルでカテゴリーidを保存しておく。
・質問に答えて貰って、該当のカテゴリーidを持つレストランを表示する。の二点が最低機能で追加機能を入れるなら、
・ユーザー登録機能の実装
・ユーザーが1店舗だけオススメのレストランを登録できる。
・レストラン検索機能
です。
レストランをカテゴリー分けして、表示しようかなと思いました。
別テーブルに保存する事で、カラムを増やせばカテゴリーを増やせるので、後々質問が多様化してカテゴリーの種類が増えた時に困らないかなと思ったのでこの様な仕様にしました。
ユーザー投稿を導入すると、どうしても検索されるレストランの質が落ちてしまう問題があるので、1ユーザー1店舗に
する事で質を保とうとしました。
またユーザーが投稿出来る様になる事で、私の秘蔵情報を公開する必要がなくなる為、レストラン検索機能を追加したいと思います。まとめ
現状最低機能までを3日で考えています。
またアプリが完成した段階でまとめを書いていきたいと思います
- 投稿日:2019-08-04T18:36:14+09:00
seedsファイルで西暦テーブルを作りたい
前記事で下の画像のミニアプリを実装しようとした際、optionタグ用に1900年から2019年までのレコードを作ろうとして七転八倒したので共有します。
seeds.rbっていうぐらいだからruby式が使えます
qiita seedデータの投入方法
【Rails入門】seedの使い方まとめ | 侍エンジニア塾ブログ(Samurai Blog)
seedsファイルのデータ投入方法について検索すると出てくる上記のリンクでは下記のようなコードを紹介しています。(例)seeds.rb2019.times do |number| Year.create(year: number) endyearsテーブルのyearカラムに0~2019年までのデータを入れるというコードです。
しかし、このコードだと0年からレコードが作られてしまいます。
僕は、ずっとこの式じゃないとデータ投入ができないという固定観念があったので、これでどうやって1900年からだけ入れればいいんだと悩みました。
しかし、seeds.rbでは普通のruby式が使えるので以下のコードでいけます(正解)seeds.rbnum = 1900 while num < 2020 Year.create(year: num) num += 1 endこれでもいけます
(正解)seeds.rb2019.times do |number| Year.create(year: number) if number >= 1900 end干支も一緒に登録する
話はミニアプリに戻りますが、当初は以下のコードでユーザーの選んだ年に対してリアクションを返そうとしていました。
js$(function(){ $(".daigo-main__year__select").on("change", function(){ //optionタグを選択すると発火 var ment = $(this).val();//値を入手 if (ment % 12 == 0) { $(".demon").text("あなたは申年ですね。これが").fadeIn(4000, function(){ $(".demon2").text("メンタリ○ムです").fadeIn(2000);//値 ÷ 12のあまりが0なら申年 }); } else if (ment % 12 == 1) { $(".demon").text("あなたは酉年ですね。これが").fadeIn(4000, function(){ $(".demon2").text("メンタリ○ムです").fadeIn(2000);//値 ÷ 12のあまりが1なら酉年 }); } else if (ment % 12 == 2) { $(".demon").text("あなたは戌年ですね。これが").fadeIn(4000, function(){ $(".demon2").text("メンタリ○ムです").fadeIn(2000);//値 ÷ 12のあまりが2なら戌年 }); } }); }); . . . .書くのがだる過ぎて干支をテーブルに登録できないか考えました。
テーブルに保存していれば下記のコードを全ての干支で使いまわせますからね。(正解)js$(function(){ $(".daigo-main__year__select").on("change", function(){ var ment = $(this).val(); $(".demon").text("あなたは"+ ment +"年ですね。これが").fadeIn(4000, function(){ $(".demon2").text("メンタリ○ムです").fadeIn(2000); }); }); });それを可能にしたのが以下のコードです。
seeds.rbnum = 1900 zyuunishi = ["申", "酉", "戌", "亥", "子", "丑", "寅", "卯", "辰", "巳", "午", "未"] while num < 2020 Year.create(year: "#{num}", eto: "#{zyuunishi[num % 12]}") num += 1 end配列の中の要素は
配列名[番号]で入手することができます。それを利用してjQuery側で行なっていた干支の仕分けを自動でしてくれるというわけです。完成!
- 投稿日:2019-08-04T17:46:57+09:00
Herokuでアプリをデプロイしたら「”We're sorry, but something went wrong.”」のエラーが出た 【Rails】
Herokuでアプリをデプロイしようとしたら、「”We're sorry, but something went wrong.”」というエラーが出た
1 ググるとlogフォルダ内のdevelopment.logに表示された原因が書かれているとの事だったので、調べるが特に問題が見当たらず。
2 次にheroku デプロイ We're sorry, but something went wrong. としてヒットした記事を参考にheroku run rails db:migrateをターミナルで実行すると解決した。
heroku run rails db:migrateとはなんなのかHeroku上でデータベースを初期化していないので、このままHeroku上のWebアプリケーションにアクセスするとエラーが発生してしまう。そこでheroku runコマンドを用いることにより、Heroku上でRakeコマンドが使えるようにするということなのかな?
- 投稿日:2019-08-04T16:07:48+09:00
本番環境でCarrierWaveでS3にアップロードした画像が表示されない時の対処
簡単なチャットアプリケーションを開発する学習で
Rails、Heroku、CarriaWave 、S3を使用して画像をアップロードした際に
以下のようになり、画像が正しく表示されませんでした
対処した時のことを忘れないように、記事を投稿したいと思います。原因を探ってみる
まずは、そもそも画像がAmazon S3の管理画面にアップロードできているのかを確認
問題なくアップロードされていました。
ファイルの記述方法は間違っていないかを確認
carrierwave.rbrequire 'carrierwave/storage/abstract' require 'carrierwave/storage/file' require 'carrierwave/storage/fog' CarrierWave.configure do |config| config.storage = :fog config.fog_provider = 'fog/aws' config.fog_credentials = { provider: 'AWS', aws_access_key_id: Rails.application.secrets.aws_access_key_id, aws_secret_access_key: Rails.application.secrets.aws_secret_access_key, region: 'ap-northeast-1' } config.fog_directory = 'バケット名' config.asset_host = 'https://s3-ap-northeast1.amazonaws.com/バケット名' endんー、カリキュラムの指示通りかけてるな
どこが悪いのかさっぱり!
解決方法
キーワードを変えながら検索をしていると同じような問題を書いてあるページを発見しました。
読んでみると、
「原因はconfig/initializers/carrierwave.rb内の、urlの指定が間違っていたからでした。以下のように asset_hostのurlの指定を修正すると、無事にストレージから画像を取得できました。」
(https://remonote.jp/rails-production-carrierwave-s3-error より引用)carrierwave.rbの書き方ミスとのこと
カリキュラムの書き方を信じるのもよくないですな
以下のようにコードを修正しましたcarrierwave.rbrequire 'carrierwave/storage/abstract' require 'carrierwave/storage/file' require 'carrierwave/storage/fog' CarrierWave.configure do |config| config.storage = :fog config.fog_provider = 'fog/aws' config.fog_credentials = { provider: 'AWS', aws_access_key_id: Rails.application.secrets.aws_access_key_id, aws_secret_access_key: Rails.application.secrets.aws_secret_access_key, region: 'ap-northeast-1' } config.fog_directory = 'バケット名' config.asset_host = 'https://s3-ap-northeast1.amazonaws.com/バケット名' #url間違い config.asset_host = 'https://バケット名.s3.amazonaws.com' #このように修正ふぅ・・なんとかなりました
最後に
いかがでしたでしょうか?
初投稿なので読みづらかったり分かりづらい点もあるかと思います。
コードの書き方は変わっていくので常に追っていかないといけないなと改めて思いました
同じエラーで悩んでいる人の助けになれたらいいなと思います参考元
「本番環境でCarrierWaveでS3にアップロードした画像が表示されない問題」の対処
https://remonote.jp/rails-production-carrierwave-s3-error
- 投稿日:2019-08-04T16:05:01+09:00
第一回Pokotarou反省会
第一回Pokotarou反省会
概要
Ruby on Railsで使えるMysqlのSeederプログラムとして作ったGemであるPokotarouの反省会。
Pokotarouのgithubページgithubに作った英語のマニュアル
現在、Pokotarouの使い方は英語学習のために英語で記述しているが、私が初学者のために
間違った表現や文法で書いてしまっており非常に読みにくいものとなっている。
英語を勉強して少しずつ改善の手を加えていきたいと思う。PokotarouHandlerに関して
ver0.1.2をリリースした際にymlファイルの設定を読み取った後に
その内容を動的に変更できるPokotarouHandlerという名前のクラスを実装した。
変更できる内容として一部の設定の削除とループ数しかないため、機能的に乏しい。
今後のアップデートで機能を増やしていこうと思う。プログラム内のコメント
改善箇所としてプログラム内のコメントが挙げられる。
得にデータ構造に関するコメントを書いたほうが個人的には、わかりやすいので
今後は記述する事にする。
例えば、プログラム内のseed_arr変数に関するデータ構造なら以下のように記述した。# seed_arr: [[col1_element, col1_element], [col2_element, col2_element]...]もちろんデータ構造に関するコメント以外も、記述して可読性の高いソースコードを目指していく。
クラス名
Pokotarouのconvert機能で使っているConverterという名前のクラスがあるが、後から見て何をしているクラスか分かりにくかったので修正し別の名前をつける。
- 投稿日:2019-08-04T15:19:51+09:00
Rspecメモ
Rspecとは
RubyでBDD(振舞駆動開発)を実施するためのテストフレームワーク。
そもそもBDD(振舞駆動開発)とは
振舞とは?
ユーザーの操作によって実行されるソフトウェアの処理であり機能。
つまり、対象における「外部から見える変化」「入力・出力」「オブジェクトのメッセージ」などの「対象における何らかのイベントにひも付く外部から見える変化」であると言える。振る舞いをテストしている」とは何か
上記のような、「対象オブジェクトにおけるメソッドの組み合わせによって外部から見える変化を記述している」、「対象がどのように何をするかを記述している」、「コミュニケーションパターンを記述している」など例で言い換えると「ある人物について個々の動作を独立に説明しているけれど、その人物を特徴付ける一連の行動を説明していない」と言い換えることができる。
RSpecとMiniTestの違い
Rspecの特徴
- DSLで記述→ロジックの自由度が低い
- 学習コストが高い
- 採用している企業が多い
- 情報が豊富
- 最初からさまざまな機能が入っていて便利
MiniTestの特徴
- 純粋なRubyで記述→言語機能が使えるため自由度が高い
- 学習コストが低い
- Rails標準のテストフレームワーク
- 採用している企業が少ない
- 実行速度が早い
- 複雑なテストを行う場合、多くのプラグインが必要となる
主なテストの種類
Modelテスト
- モデルの状態が有効になっているか。
- バリデーションが効いているか。
- クラスメソッドとインスタンスメソッドの動作。
System テスト
- Rails 5.1から使用可能となった統合テスト。
- Feature テストと役割は同じだがテスト失敗時スクショを撮影するgemのインストールが不要。
- driven_byを使って、specごとにブラウザを簡単に切り替えることができる。
- テスト終了時にDBが自動的にロールバックされる
Request(結合) テスト
- ルーティングを含めたコントローラー、モデル、ビューを通したテストを行う。また、リクエストに対して正しいレスポンスが返されることを確認する。
その他のテストは利用頻度が少なかったり上記のテストに置き換えが推薦されていたりするので割愛。
コードの基本形
describe [仕様を記述する対象(テスト対象)], type: [Specの種類] do context [ある状況・状態] do before do [事前準備] end it [仕様の内容(期待の概要)] do [期待する動作] end end end
- テストを整理・分類する・・describe,context
テストコードを実行する・・before、it
before
- 何を記述しようとしているのかを記述
context
- テストの内容を「状況・状態」のバリエーションごとに分類する
it
- 期待する動作を文章と、ブロック内のコードで記述
(参考)
https://www.atmarkit.co.jp/ait/articles/1404/30/news022.htmlhttps://qiita.com/umeziro_v2/items/edd7df47a5aa378af721#_reference-e2a604932337f846bc8e
- 投稿日:2019-08-04T14:43:13+09:00
rspec : subjectがなくてもテストは通る。その場合の書き方。
subjectを使った場合
spec/requests/articles_spec.rbrequire 'rails_helper' RSpec.describe "Articles", type: :request do describe "GET /api/v1/articles" do subject { get(api_v1_articles_path) } ←ここでリクエストのpathをsubjectで指定。こうすることで subject のみの記述で同じリクエストを指定できる。ドライに書ける。 let(:article_count) { 5 } before do create(:user, :with_articles, article_count: article_count) end it "articlesの一覧を取得できる" do subject ←このsubject一行で、上で指定したpathを同じ意味になる。(同じpathにリクエストを送る) res = JSON.parse(response.body).count expect(res).to eq article_count end end endsubjectを使わない場合
spec/requests/articles_spec.rbrequire 'rails_helper' RSpec.describe "Articles", type: :request do describe "GET /api/v1/articles" do let(:article_count) { 5 } before do create(:user, :with_articles, article_count: article_count) end it "articlesの一覧を取得できる" do get(api_v1_articles_path) ←subjectを使わずにpathの指定 res = JSON.parse(response.body).count expect(res).to eq article_count end end end
- 投稿日:2019-08-04T12:11:56+09:00
blazer で SQL の LIKE 句による部分一致検索で変数を使う
はじめに
Rails アプリにおいて、直接 SQL を実行してレポートを作成するときに、blazer という gem を使っています。
こちらの gem で SQL の LIKE 句を使い、部分一致のキーワードで変数を使おうと思ったときに少しハマったので、調べたことをまとめます。
課題
以下のように、LIKE 句を使った部分一致で、
hogeというキーワードが含まれているnameを検索する SQL を書くとします。SELECT name FROM users WHERE name LIKE '%hoge%'この
hogeの部分を変数にして、任意のキーワードで部分一致を使えるようにすると便利そうだと思ったので、hogeの部分を{keyword}と書き換えました。
※変数の使い方は README 参照SELECT name FROM users WHERE name LIKE '%{keyword}%'しかし、こちらで例えば
fugaというキーワードで SQL を実行しようとすると、fugaの両端がシングルコーテーションで囲まれてしまい、SQL 構文エラーになってしまいました。SELECT name FROM users WHERE name LIKE '%'fuga'%'ここからシングルコーテーションを外せないかなど色々試したのですがうまくいかず、ハマった状態が続きました。
解決策
あれこれ調べていたところ、以下の issue に解決策が記載されていました。
Support for variables that are already inside quotes · Issue #179 · ankane/blazer · GitHub変数の両端からシングルコーテーションを取り除くのではなく、それぞれを文字列として扱い、連結させれば OK とのことでした。
DB で PostgreSQL を使っている場合は、変数と
%の間に||演算子を入れます。SELECT name FROM users WHERE name LIKE '%' || {keyword} || '%'DB で MySQL を使っている場合は、
CONCAT関数で連結させます。SELECT name FROM users WHERE name LIKE CONCAT('%', {keyword}, '%')終わりに
使っているライブラリで困ったときには、そのリポジトリの issue を追ってみるとヒントがあることが多いなと思いました。
issue ともっと親しくなっていきたいと思います。参考
- 投稿日:2019-08-04T11:16:35+09:00
rails generate react:install実行時のrun() in thread failed: inotify event queue has overflowed対応
現象
rails webpacker:installを実行するとrun() in thread failed: inotify event queue has overflowedと表示される。
app/assets/javascripts/application.jsが作成されない。環境
docker-composeでruby:2.6.3をベースに構築。
対応
方法その1.Dockerの設定を変更する。
環境設定→AdvancedのCPUs,Memory,Swapの値を増加する。
方法その2.コンテナ内のファイル以下の記述を追加しsysctl設定にロードする。
/etc/sysctl.conffs.inotify.max_user_watches = 999999 fs.inotify.max_queued_events = 999999 fs.inotify.max_user_instances = 999999以下のコマンドを実行
sudo sysctl -p補足:以下のエラーが表示される場合、privilegedでコンテナを起動する必要がある。
sysctl: setting key "fs.inotify.max_user_watches": Read-only file systemprivilegedを以下の通り記載してコンテナを起動し、再度コンテナ内でsudo sysctl -pを実行する。
docker-compose.ymlversion: '3' services: web: privileged: true結果
rails generate react:installでエラーが出ず、正しくapp/assets/javascripts/application.jsが作成される!
参考にさせていただいたサイト
https://github.com/guard/listen/wiki/Increasing-the-amount-of-inotify-watchers
https://github.com/guard/rb-inotify/issues/61
https://qiita.com/osamunmun/items/1786aac5904439522d72
- 投稿日:2019-08-04T09:06:19+09:00
Rails ルーティングの基礎とRESTful
はじめに
Railsのルーティングについて調べましたので、まとめようと思います。
Railsのルーティングについて一気にまとめてしまうと長くなってしまいますので、
今回は
- Railsのルーティングの基礎
- RESTful
に絞りました。
ルーティングの基礎
ルーティングとは
リクエストのURLに応じて、どの処理を実行するかを決定するしくみを指します。
Railsの場合、次の手順で実行するコントローラとアクションを決定します。
- クライアントがリクエストを送る
- パスを解析し、ルート定義を検索する
- 検索されたルート定義に基づいて対応するコントローラ、アクションを呼び出す
ルーティングの設定
ルーティングの設定は/config/routes.rbに定義します。
routes.rbRails.application.routes.draw do get 'members' => 'members#index' endこれは
リクエストのURLの末尾がmembersだった場合 =>
membersコントローラのindexアクションを呼び出す
と定義しています。ルーティングとコントローラの設定例
例えば、次のコントローラとアクションを定義して
members_controller.rbclass MembersController < ApplicationController def index end end次のルーティングを定義して
routes.rbRails.application.routes.draw do get 'members' => 'members#index' end次のリクエストを送信すると
※ http://localhost:3000/の部分はホスト名で、Railsのデフォルトポートは3000です。http://localhost:3000/membersMembersコントローラのindexアクションが呼ばれます。
RESTful
Railsのルート設計
RESTの性質を持つルート設計のことをRESTfulと言います。
Railsのルート設計はRESTfulです。
※ RESTfulでないルート設計も可能です。しかしRailsにはRESTfulなルート設計が前提の機能も存在するため、注意が必要です。RESTとは
以下の原則に沿った Webサービスの設計モデルを指します。
- セッションなどの状態管理を行わない
- 情報を操作する命令が体系化されて定義・共有される
- 情報に対して汎用的な構文で一意に識別される
- 情報に、別の情報や別の状態へのリンクを含めることができる
一つ一つ具体的にまとめてみます。
セッションなどの状態管理を行わない
クライアントの送信する情報には、全てのやりとりが含まれています。
サーバはクライアントの状態を保持しません。
このようなクライアントとサーバのやりとりはステートレスと言われます。
逆に状態を保持する場合はステートフルと言われます。例としてECサイトで買い物する場合
ステートフルの場合
1. 商品Aをカートに入れる
2. 商品Bをカートに入れる
3. カート内の商品を購入ステートレスの場合
1. 商品Aをカートに入れる
2. 商品Aと商品Bをカートに入れる
3. カート内の商品を購入ステートフルの場合、サーバ側でカートに入れた商品の状態を保持しているため、クライアントは追加する商品の情報のみ送信します。
ステートレスの場合、サーバ側でカートの状態を保持していないため、クライアントは送信する情報にすべてのやりとりを含める必要があります。情報を操作する命令が体系化されて定義・共有される
なに(リソース)に対してどうするか(HTTPメソッド)でルート定義を設定すること
HTTPメソッドとはクライアントがサーバに対して出す依頼のことで、主に次のようなものがあります。
- GET:取得
- POST:作成
- PUT:更新
- PATCH:部分更新
- DELETE:削除
リソースとはユーザ情報や画像データなど、情報全般のことを指します。
例えば以下のルーティングの場合
routes.rbRails.application.routes.draw do get 'members' => 'members#index' endMembers(リソース)をGET(取得)するとルート設計しています。
情報に対して汎用的な構文で一意に識別される
すべてのリソースはURIで識別されるということです。
情報に、別の情報や別の状態へのリンクを含めることができる
ハイパーテキスト(他の文書への参照を埋め込める)を拡張したハイパーメディア(文字情報に加え、画像や音声などの情報を扱えるようにし、対応づけたもの)を使おうということです。
ハイパーメディアを用いることで、現在のアプリケーションの状態や、違う情報へのリンクなどを表現します。メリット
- ステートレスなため、サーバ側の負荷が少ない
- HTTP標準のメソッドを使用することで、一貫性のあるルートを設計できる
- URIに規則が生まれるため、アプリ開発者はリソースを管理しやすい
おわりに
RailsのルーティングとRESTfulについてまとめました。
間違っているところなどがありましたら、教えていただけるとありがたいです。
- 投稿日:2019-08-04T01:07:32+09:00
Railsチュートリアル(第5章)
はじめに
Railsチュートリアルの第5章が終わりました。
ポイントだけメモしておきます。条件付きコメント
以下のように記述することで、Internet Explorerのバージョンが9以下の場合のみ、コメント内の処理が実行されます。
<!--[if lt IE 9]> <script src="//cdnjs.cloudflare.com/ajax/libs/html5shiv/r29/html5.min.js"> </script> <![endif]-->リンク用のヘルパー
以下のように記述することで、リンクを記述することができます。
最終的にはaタグになります。<%= link_to "テキスト", "URL" %>CSSの記述
app/assets/stylesheets/ディレクトリ配下に置いたcssやscssファイルはアプリケーション全体で使用することができます。
また、bootstrapを使用する際は、ファイルの先頭に以下の内容を記述します。@import "bootstrap-sprockets"; @import "bootstrap";パーシャル
viewのコードをひとまとまりにして別ファイルにすることができます。これによって似たような記述を使いまわしたり、コードをわかりやすくすることができます。
パーシャルのファイル名は、_から始まる必要があります。パーシャルをviewに組み込む場合は、以下のように記述します。
<%= render ”ファイルパス” %>例えば、以下であれば
app/view/layouts/_header.html.erbというファイルの内容を埋め込むことになります。
renderに記述する際は、先頭の_を外して記述します。<%= render `layouts/header` %>名前付きルート
routes.rbに記述したルートに名前を付けてリンク等に使うことができます。
以下のように記述します。config/routes.rbroot 'static_pages#home' get '/help', to: 'static_pages#help' get '/about', to: 'static_pages#about' get '/contact', to: 'static_pages#contact'rootで記述したルートには、
root_pathでアクセスできます。
その他のルートは、上記の例だと、以下のようにアクセスできます。get '/help', to: 'static_pages#help' # help_pathによって'static_pages#help'にアクセスする get '/about', to: 'static_pages#about' # about_pathによって'static_pages#about'にアクセスする get '/contact', to: 'static_pages#contact' # contact_pathによって'static_pages#contact'にアクセスするこれで、
link_toを記述すると以下のようになります。<%= link_to "About", about_path %>また、以下のように
asを使って記述することで、名前付きルートの名前を変えることができます。get '/about', to: 'static_pages#about', as: 'hoge'






























