20190804のRailsに関する記事は15件です。

RubyのRailsをMySQLでHerokuにあげてみた

今までの麻雀アプリは一人でずっとやるだけだったので、
もう少しデータ的なのを集められるようになりたいなーと思って
ちょっと改良しました。

https://rubymahjong.herokuapp.com/

↓こんなの
スクリーンショット 2019-07-16 2.51.18.png

みんなのあがり回数とあがりまでの平均ツモ数を表示できるようにしました!

◇開発言語
 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/1419324649

alias 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/a380ebb1fd156c14c25b

brew install mysql

railsプロジェクト作成

必要なものは全部インストールできたので、早速
mysqlを利用するRailsプロジェクトを作成します。
といっても、さすがRails。コマンド一つだけですぐにできます。

rails new ./ -d mysql

適当なフォルダにて上記コマンドを実行すればOKです。
VScodeにてコンソールを表示し、上記コマンドを実行すれば必要なファイルが勝手に作成されます。

スクリーンショット 2019-08-01 14.48.40.png

config/database.ymlを確認すると、ちゃんとMySQLを使う設定になってますね!

んで、早速Railsの起動コマンド「rails server」を実行。
デフォルトだと地球儀の絵がTOPページに表示されるはず。
スクリーンショット 2019-08-01 14.37.07.png
うーん失敗。

ただ、以下のメッセージからするに、mysqlに接続できていない感じ。

Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)

というか、そもそもsqlサーバーを起動していないので、そりゃDB接続できないよってエラー出ますよね。
ということで、以下コマンドを実行してsqlサーバーを起動。

mysql.server start

スクリーンショット 2019-08-01 14.42.44.png

うん。sqlサーバーは起動できたみたいです。
じゃぁもう一度Railsを起動し画面を確認!
スクリーンショット 2019-08-01 14.51.31.png
まぁ、エラーになるよね。今回のエラー原因は以下の通り。

Unknown database 'project_development'

project_developmentってデータベースがないよーってい言ってますね。
project_developmentは、config/database.ymlで設定している
データベースですね。
mySqlにログインしようとしてもproject_developmentはないからエラーになりますね。
まぁ、project_developmentを作ってないので当たり前ですね。

スクリーンショット 2019-08-01 14.56.18.png

なので、project_developmentを作ります。
ただ、これもRailsを利用して作成することができます。
以下コマンドを実行するだけ!

rails db:create

スクリーンショット 2019-08-01 14.59.33.png

はい!できましたー。
じゃぁもう一度Railsを起動し画面を確認!

スクリーンショット 2019-08-01 15.01.42.png

地球の絵!
見慣れた画像が表示されました!
とりあえず、これで環境面は一通りできました!

テーブル作成

今回は、上がりまでにかかった自摸の回数をテーブルに記録させていきたいと思います。
Railsのコマンドを実行すると、テーブルやそのテーブルにアクセスするための機能(プログラムファイル)
も自動でできます。

rails generate scaffold WonCount name:string wonCount:integer

スクリーンショット 2019-08-01 15.16.49.png

ですが、上記コマンドだけだと肝心のテーブル自身は作成されません。
スクリーンショット 2019-08-01 15.24.24.png

マイグレーションを実行する必要があります。
と言っても難しいことは何もしません。
以下コマンドを実行するだけです。

rails db:migrate

スクリーンショット 2019-08-01 15.21.15.png

スクリーンショット 2019-08-01 15.34.24.png

参考: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-assets

rails_12factor

rails_12factorというのをHeroku上で利用できるように設定します。
rails_12factorは、Herokuでのログを見れるようにするgem(Rubyのライブラリ)です。
Gemfileに以下記述を追加するだけでOKです。

group :production do
  gem 'rails_12factor'
end

Procfile作成

Procfileを作成し、Heroku上での起動コマンドを記述します。
以下記述だけでOK。

web: bundle exec rails server -p $PORT

スクリーンショット 2019-08-04 21.11.10.png

Herokuにアップ

はい。ここまで出来たらHerokuにアップします。
HerokuGitにアップする方法もありますが、
自身のGitHubにアップしたプロジェクトを利用します。

んで、プロジェクトアップロード後にWebサイトを確認。

スクリーンショット 2019-08-04 21.32.05.png

はい。失敗〜。
Herokuのログを見ます。コマンドプロンプトから以下コマンドを実行〜。

heroku logs --tail --app rubymahjong

※「rubymahjong」は、Herokuにアップしたプロジェクト名です。
スクリーンショット 2019-08-04 21.32.11.png

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-2

heroku addons:create cleardb:ignite --app rubymahjong

スクリーンショット 2019-08-04 22.20.04.png

Heroku上の「Overview」を見ると、MySQLがアドオンされたことが分かりますね。
スクリーンショット 2019-08-04 22.10.24.png

以下コマンドを実行してコンフィグを確認しても、MySQLが追加されたことが分かります。

heroku config --app rubymahjong

【変更前】
スクリーンショット 2019-08-04 22.24.38.png
【変更後】
スクリーンショット 2019-08-04 22.23.52.png

CLEARDB_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

スクリーンショット 2019-08-04 22.56.06.png

変更後、またコンフィグを確認してみます。
【変更後】
heroku config --app rubymahjong
スクリーンショット 2019-08-04 23.10.33.png
DATABASE_URLが追加されてますね!

この状態でブラウザから画面を確認すると…。
スクリーンショット 2019-08-04 21.32.05.png

エラー。でも、ログの内容は変わってます。
スクリーンショット 2019-08-04 23.16.17.png

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

スクリーンショット 2019-08-04 23.22.31.png

なんか出来てる感じですね!
早速ブラウザから画面を確認してみます。

スクリーンショット 2019-08-04 23.24.49.png
できました!
きちんとあがり回数をDBに登録し、その結果を出力出来てます!

Herokuって便利ですねー。
Rails+MySQLってかなりのWebサービスで利用されてそうで、
その環境が簡単に作れると色々なことが出来て夢が広がりますね!


今回のプログラムは以下GitHubにあげてます。
https://github.com/kph7m/rubymahjong

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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
end
rake db:pull

Reference: https://martinschurig.com/posts/2015/02/pulling-production-database-to-local-machine-rails-task/

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

UnicornがResource temporarily unavailableを吐いたらbacklogの値を確認してみる

背景

railsアプリケーションをnginx+unicornで稼働させている際、以下のエラーが発生していました。
nginxとunicorn間は、UNIXソケットで通信しています。

nginx.log
connect() 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.conf
net.core.somaxconn = 256

railsアプリケーション上での設定は、listenする際に指定可能です。
config/unicorn.rbに指定した値は、OSでの上限より大きくはなりません。

config/unicorn.rb
listen "/tmp/unicorn.sock", backlog: 256

unicornを再起動すると、以下のようにbacklogの値が変更されていることを確認できます。

$ ss -ax | grep -e unicorn
u_str  LISTEN     0      256    /tmp/unicorn.sock 38120                 * 0
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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.conf
fs.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 system

privilegedを以下の通り記載してコンテナを起動し、再度コンテナ内でsudo sysctl -pを実行する。

docker-compose.yml
version: '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

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

『レストラン検索アプリ』の制作過程

はじめに

今回自作アプリを作るのでその過程を残しておきます。(備忘録)
現在制作中なので随時更新されていきます。

目次

※別記事をアップしたら随時更新していきます

アプリ概要

●使用する技術
今回はRails+mysql+heroku+bootstrapでアプリを作っていきます。
AWSと迷いましたが、チーム開発でAWSを触っていたので省略してherokuを使います。
もし時間があれば、AWSに移すかもしれません。

●解決したい事とアプリへの想い
アプリを作ったキッカケは、ミシュランや食べログなど様々な観点の評価軸をもつサイトがあるが、200店舗程実際に食べてみて、どれも当てにならないと思っていました。(勿論個人の好みもあります)
いつもレストランに行ってトライアンドエラーを繰り返す中で、一番信用出来る情報源は、食通や料理人が美味しいと言うお店だと思いました。
なので私が知っている限りですが、それを紹介できるアプリを作ろうと思ったのがきっかけです。
しかし問題として、私自身美味しいお店を広めたくありません!過去好きなお店が突然点数アルゴリズムが変わったとか
なんとかで、予約が取れなくなる苦い経験を何度かしています。(お店側も結構似た想い持ってるところが多いです、、、)
なので、今回は質問に答えて、それに当てはまる1店舗だけを紹介するという形にしました。拘りも出せて一石二鳥です。
●実装内容
内容としては
・DBにレストラン情報と別テーブルでカテゴリーidを保存しておく。
・質問に答えて貰って、該当のカテゴリーidを持つレストランを表示する。

の二点が最低機能で追加機能を入れるなら、
・ユーザー登録機能の実装
・ユーザーが1店舗だけオススメのレストランを登録できる。
・レストラン検索機能
です。
レストランをカテゴリー分けして、表示しようかなと思いました。
別テーブルに保存する事で、カラムを増やせばカテゴリーを増やせるので、後々質問が多様化してカテゴリーの種類が増えた時に困らないかなと思ったのでこの様な仕様にしました。
ユーザー投稿を導入すると、どうしても検索されるレストランの質が落ちてしまう問題があるので、1ユーザー1店舗に
する事で質を保とうとしました。
またユーザーが投稿出来る様になる事で、私の秘蔵情報を公開する必要がなくなる為、レストラン検索機能を追加したいと思います。

まとめ

現状最低機能までを3日で考えています。
またアプリが完成した段階でまとめを書いていきたいと思います

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

seedsファイルで西暦テーブルを作りたい

前記事で下の画像のミニアプリを実装しようとした際、optionタグ用に1900年から2019年までのレコードを作ろうとして七転八倒したので共有します。 
qiitad.mov.gif

seeds.rbっていうぐらいだからruby式が使えます

qiita seedデータの投入方法
【Rails入門】seedの使い方まとめ | 侍エンジニア塾ブログ(Samurai Blog)
seedsファイルのデータ投入方法について検索すると出てくる上記のリンクでは下記のようなコードを紹介しています。

(例)seeds.rb
2019.times do |number|
  Year.create(year: number)
end

yearsテーブルのyearカラムに0~2019年までのデータを入れるというコードです。
しかし、このコードだと0年からレコードが作られてしまいます。
僕は、ずっとこの式じゃないとデータ投入ができないという固定観念があったので、これでどうやって1900年からだけ入れればいいんだと悩みました。
しかし、seeds.rbでは普通のruby式が使えるので以下のコードでいけます

(正解)seeds.rb
num = 1900
while num < 2020
  Year.create(year: num)
  num += 1
end

これでもいけます

(正解)seeds.rb
2019.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.rb
num = 1900
zyuunishi = ["申", "酉", "戌", "亥", "子", "丑", "寅", "卯", "辰", "巳", "午", "未"]
while num <  2020
  Year.create(year: "#{num}", eto: "#{zyuunishi[num % 12]}")
  num += 1
end

配列の中の要素は配列名[番号]で入手することができます。それを利用してjQuery側で行なっていた干支の仕分けを自動でしてくれるというわけです。

完成!

スクリーンショット 2019-08-04 18.32.31.png

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Herokuでアプリをデプロイしたら「”We're sorry, but something went wrong.”」のエラーが出た   【Rails】

Herokuでアプリをデプロイしようとしたら、「”We're sorry, but something went wrong.”」というエラーが出た

スクリーンショット 2019-08-04 16.46.35.png

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コマンドが使えるようにするということなのかな?

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

本番環境でCarrierWaveでS3にアップロードした画像が表示されない時の対処

簡単なチャットアプリケーションを開発する学習で
Rails、Heroku、CarriaWave 、S3を使用して画像をアップロードした際に
以下のようになり、画像が正しく表示されませんでした

image.png
対処した時のことを忘れないように、記事を投稿したいと思います。

原因を探ってみる

まずは、そもそも画像がAmazon S3の管理画面にアップロードできているのかを確認
image.png

問題なくアップロードされていました。

ファイルの記述方法は間違っていないかを確認

carrierwave.rb
require '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.rb
require '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' #このように修正

すると、画像を投稿した際に表示されるようになりました。
image.png

ふぅ・・なんとかなりました

最後に

いかがでしたでしょうか?
初投稿なので読みづらかったり分かりづらい点もあるかと思います。
コードの書き方は変わっていくので常に追っていかないといけないなと改めて思いました
同じエラーで悩んでいる人の助けになれたらいいなと思います

参考元

「本番環境でCarrierWaveでS3にアップロードした画像が表示されない問題」の対処
https://remonote.jp/rails-production-carrierwave-s3-error

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

第一回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という名前のクラスがあるが、後から見て何をしているクラスか分かりにくかったので修正し別の名前をつける。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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.html

https://qiita.com/umeziro_v2/items/edd7df47a5aa378af721#_reference-e2a604932337f846bc8e

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

rspec : subjectがなくてもテストは通る。その場合の書き方。

subjectを使った場合

spec/requests/articles_spec.rb
require 'rails_helper'

RSpec.describe "Articles", type: :request do
  describe "GET /api/v1/articles" do
    subject { get(api_v1_articles_path) }  ←ここでリクエストのpathsubjectで指定。こうすることで 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
end

subjectを使わない場合

spec/requests/articles_spec.rb
require '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

参考
https://qiita.com/takutotacos/items/f65b47d18c124110eebd

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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 ともっと親しくなっていきたいと思います。

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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.conf
fs.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 system

privilegedを以下の通り記載してコンテナを起動し、再度コンテナ内でsudo sysctl -pを実行する。

docker-compose.yml
version: '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

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Rails ルーティングの基礎とRESTful

はじめに

Railsのルーティングについて調べましたので、まとめようと思います。
Railsのルーティングについて一気にまとめてしまうと長くなってしまいますので、
今回は

  • Railsのルーティングの基礎
  • RESTful

に絞りました。

ルーティングの基礎

ルーティングとは

リクエストのURLに応じて、どの処理を実行するかを決定するしくみを指します。
Railsの場合、次の手順で実行するコントローラとアクションを決定します。

  1. クライアントがリクエストを送る
  2. パスを解析し、ルート定義を検索する
  3. 検索されたルート定義に基づいて対応するコントローラ、アクションを呼び出す

ルーティングの設定

ルーティングの設定は/config/routes.rbに定義します。

routes.rb
Rails.application.routes.draw do
  get 'members' => 'members#index'
end

これは
リクエストのURLの末尾がmembersだった場合 =>
membersコントローラのindexアクションを呼び出す

と定義しています。

ルーティングとコントローラの設定例

例えば、次のコントローラとアクションを定義して

members_controller.rb
class MembersController < ApplicationController
  def index
  end
end

次のルーティングを定義して

routes.rb
Rails.application.routes.draw do
  get 'members' => 'members#index'
end

次のリクエストを送信すると
※ http://localhost:3000/の部分はホスト名で、Railsのデフォルトポートは3000です。

http://localhost:3000/members

Membersコントローラのindexアクションが呼ばれます。

RESTful

Railsのルート設計

RESTの性質を持つルート設計のことをRESTfulと言います。
Railsのルート設計はRESTfulです。
※ RESTfulでないルート設計も可能です。しかしRailsにはRESTfulなルート設計が前提の機能も存在するため、注意が必要です。

RESTとは

以下の原則に沿った Webサービスの設計モデルを指します。

  1. セッションなどの状態管理を行わない
  2. 情報を操作する命令が体系化されて定義・共有される
  3. 情報に対して汎用的な構文で一意に識別される
  4. 情報に、別の情報や別の状態へのリンクを含めることができる

一つ一つ具体的にまとめてみます。

セッションなどの状態管理を行わない

クライアントの送信する情報には、全てのやりとりが含まれています。
サーバはクライアントの状態を保持しません。
このようなクライアントとサーバのやりとりはステートレスと言われます。
逆に状態を保持する場合はステートフルと言われます。

例としてECサイトで買い物する場合

ステートフルの場合
1. 商品Aをカートに入れる
2. 商品Bをカートに入れる
3. カート内の商品を購入

ステートレスの場合
1. 商品Aをカートに入れる
2. 商品Aと商品Bをカートに入れる
3. カート内の商品を購入

ステートフルの場合、サーバ側でカートに入れた商品の状態を保持しているため、クライアントは追加する商品の情報のみ送信します。
ステートレスの場合、サーバ側でカートの状態を保持していないため、クライアントは送信する情報にすべてのやりとりを含める必要があります。

情報を操作する命令が体系化されて定義・共有される

なに(リソース)に対してどうするか(HTTPメソッド)でルート定義を設定すること
HTTPメソッドとはクライアントがサーバに対して出す依頼のことで、主に次のようなものがあります。

  • GET:取得
  • POST:作成
  • PUT:更新
  • PATCH:部分更新
  • DELETE:削除

リソースとはユーザ情報や画像データなど、情報全般のことを指します。

例えば以下のルーティングの場合

routes.rb
Rails.application.routes.draw do
  get 'members' => 'members#index'
end

Members(リソース)をGET(取得)するとルート設計しています。

情報に対して汎用的な構文で一意に識別される

すべてのリソースはURIで識別されるということです。

情報に、別の情報や別の状態へのリンクを含めることができる

ハイパーテキスト(他の文書への参照を埋め込める)を拡張したハイパーメディア(文字情報に加え、画像や音声などの情報を扱えるようにし、対応づけたもの)を使おうということです。
ハイパーメディアを用いることで、現在のアプリケーションの状態や、違う情報へのリンクなどを表現します。

メリット

  • ステートレスなため、サーバ側の負荷が少ない
  • HTTP標準のメソッドを使用することで、一貫性のあるルートを設計できる
  • URIに規則が生まれるため、アプリ開発者はリソースを管理しやすい

おわりに

RailsのルーティングとRESTfulについてまとめました。
間違っているところなどがありましたら、教えていただけるとありがたいです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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.rb
  root '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'
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む