- 投稿日:2020-04-26T21:01:01+09:00
ActiveModel::SerializerのRspec
はじめに
SerializerのRSpecについて備忘録で残しておきます。
参考にしたのはこちらのドキュメント
ソースコード
Serializerを使って、
id
、name
、user_serializer.rbclass UserSerializer < ActiveModel::Serializer attribute :id attribute :name attribute :email endそのテストコードがこちら
ポイントだと思うところはこちらの2つ
1. Serializerのインスタンスを生成する必要がある
2..to_json
メソッドのオプションを使用して、返ってくるデータのカラムを指定する必要があるアソシエーションがある場合は、
include
オプションを利用するとうまいこと書けると思います。user_serializer_spec.rbrequire 'rails_helper' RSpec.describe "UserSerializer", type: :serializer do context "when create user" do let(:user) { create(:user) } it "matches to serialized JSON" do serializer = UserSerializer.new(user) expect(serializer.to_json).to eq(user.to_json(:only => [:id, :name, :email])) end end end
- 投稿日:2020-04-26T20:03:43+09:00
Capistranoを噛み砕く
近況報告
実はコーヒーマイスターを前職で取得した経緯がありまして,若干のコーヒーの知識があるので,少しひけらかしたいと思います。まず,コーヒーってどんな飲み物のイメージがあります?多分,苦いイメージですよね。では,現在世界的に高品質なコーヒーはどのように評価されているでしょうか。実は苦さの評価はありません。酸味の評価が主流です。
理由はいたって簡単。苦味は焙煎によって生まれるものであり,酸味はコーヒー豆がそもそも持っているものだからです。細かい説明はしませんが,生のコーヒー豆は食べられたものではありません,それを美味しくするために火を入れます。その時に豆の成分が焦げて苦味になります。酸味は熱によって分解されていくので,結果として深煎りのコーヒーは酸味のないものになります。一方,苦味は焙煎度合いや焙煎師の腕,設備により変化します。ということは,豆が本来持っている酸味が評価の基準になるのはまあ納得ですね。
ただ,この評価はスペシャリティコーヒー(世界のコーヒー生産のうち10%程度に該当する)の概念が生まれた10数年前のものであり,以前は苦味,そもそもそんな評価なかったかも。。。今後も同じ評価をしていくとは限りません。やはり常に情報は更新されていきます。だから,常にアンテナを張っていないと時代遅れになっちゃいますね。全てが動いているのに自分が動かなかったら動いている相手から見たら不安定です。だから動くこと,不安定であることこそが安定ってね。
今回の目標
Capistranoで実施していることの言語化
大まかな流れ
・Capistranoについて
・Capistrano導入
・各ファイルの設定事前準備
デプロイ環境整備
rails5.2以降ならマスターキーを本番環境に環境変数にして入れといてね
ruby 2.5.1Capistranoについて
一言で言えば,自動デプロイツールです。
デプロイには
SSH内の情報(アプリケーション)の更新
SSH接続
アセットコンパイル更新
Unicorn再起動
といくつかコードを打ち込んでいく必要があります。ただCapistranoを導入さえできれば,
** bundle exec cap production deploy**
これだけで上の作業が終了します。
個人的にはCircleCiを勉強して導入したかったのですが,間に合わずカリキュラムのこちらをCapistrano導入
railsにおいてCapistranoにはGemが存在します。そこからチョチョイと生成しましょう。
gemfile.group :development, :test do gem 'capistrano' gem 'capistrano-rbenv' gem 'capistrano-bundler' gem 'capistrano-rails' gem 'capistrano3-unicorn' endterminal.$ bundle install $bundle exec cap install ⇨gemfileにあるものを参照してcap(istrano)の関連ファイルをインストールこれで1つのフォルダと2つのファイルが生成されます
◆capfile----capistranoで実行することを決めるファイル
◆deploy-----デプロイする環境ごとに設定されるファイル
・staging.rb-----ステージング環境(つまり開発環境,テスト環境)に適用される
・pruduction.rb--本番環境に適用される
◆deploy.rb--デプロイする内容を決めるフォルダ
capfileで実行することをきめて,残りがGithubへの接続に必要なsshキーの指定、デプロイ先のサーバのドメイン、AWSサーバへのログインユーザー名、サーバにログインしてからデプロイのために何をするか、といった設定が入るわけです。各ファイルの設定
capfile
capfile.require "capistrano/setup" ←準備しますー(これ抜けてたら動かない) require "capistrano/deploy" ←デプロイ実行するねー require 'capistrano/rbenv' ←rbenvの状態みるね require 'capistrano/bundler' ←必要なGem確認するね require 'capistrano/rails/assets' ←アセットファイルをコンパイルするね require 'capistrano/rails/migrations' ←DB:migrateするね require 'capistrano3/unicorn' ←unicorn再起動するね Dir.glob("lib/capistrano/tasks/*.rake").each { |r| import r } ⇨ディレクトリ内の.rakeを昇順で抽出に編集
pruduction.rbpruduction.rbserver '12.345.678.90'←用意したElastic I, user: 'ec2-user', roles: %w{app db web} |「どのサーバーつなぐ?」,「ユーザー名は?」「マイグレートするのは(データベース選択)」
staging.rbは今回必要ないので無視deploy.rb
deploy.rb# capistranoのバージョンを記載。固定のバージョンを利用し続け、バージョン変更によるトラブルを防止する lock '<Capistranoのバージョン>'←ローカルで確認 # Capistranoのログの表示に利用する set :application, '自身のアプリケーション名' # どのリポジトリからアプリをpullするかを指定する set :repo_url, 'git@github.com:<Githubのユーザー名>/<レポジトリ名>.git' # バージョンが変わっても共通で参照するディレクトリを指定 set :linked_dirs, fetch(:linked_dirs, []).push('log', 'tmp/pids', 'tmp/cache', 'tmp/sockets', 'vendor/bundle', 'public/system', 'public/uploads') set :rbenv_type, :user set :rbenv_ruby, '<このアプリで使用しているrubyのバージョン>' #ローカルで確認 # どの公開鍵を利用してデプロイするか set :ssh_options, auth_methods: ['publickey'], keys: ['****.pem 自分のに書き換える'] # プロセス番号を記載したユニコーンファイルの場所はここだよ set :unicorn_pid, -> { "#{shared_path}/tmp/pids/unicorn.pid" } # Unicornの設定ファイルの場所(ローカルの位置と同じ) set :unicorn_config_path, -> { "#{current_path}/config/unicorn.rb" } set :keep_releases, 5 # デプロイ処理が終わった後、Unicornを再起動するための記述 after 'deploy:publishing', 'deploy:restart' namespace :deploy do task :restart do invoke 'unicorn:restart' end endに編集
◆set :xx, xx ⇨DSL(Domain-Specific Language)の一種
ある特定の処理における効率をあげるために特化した形の文法を擬似的に用意したプログラムです。
上記のset :名前, 値について、これは言わば変数のようなものです。
例えばset: Name, 'value' と定義した場合、fetch Name とすることで 'Value'が取り出せます。
また、一度setした値はdeploy.rbやproduction.rbなどの全域で取り出すことができます。
また、ファイル内には、desc '◯◯'やtask:XX doといった記述がよく見受けられます。これは、先ほどCapfileでrequireしたものに加えて追加のタスクを記述している形です。ここで記述したものもcap deploy時に実行されることとなります。Capistranoによる自動デプロイ後のディレクトリ構成について
一度Capistranoによる自動デプロイを実行すると、本番環境のアプリケーションのディレクトリが変化します。
Capistranoによるアプリのバックアップなど、複数のディレクトリが作成されます。その中でも特に重要なのが、releases、current、sharedディレクトリです。releasesディレクトリ
capistranoを通じてデプロイされたアプリは、releasesというフォルダにひとまとめにされます。
ここに過去分のアプリが残っていることにより、デプロイ時に何か問題が発生しても一つ前のバージョンに戻ったりすることができます。
そして、その過去分の保存数を指定しているのがdeploy.rbのset :keep_releasesの記述となります。今回は5つ、過去のバージョンを保存するよう設定しました。currentディレクトリ
releasesフォルダの中で一番新しいものが、自動的にcurrentというフォルダ内にコピーされているような状態になります。そのため、このcurrent内に入っているアプリの内容が、現在デプロイされている内容ということになります。
db:seedもここに入れないと反映されない。
sharedディレクトリ
バージョンが変わっても共通で参照されるディレクトリが格納されるディレクトリです。具体的には、log、public、tmp、vendorディレクトリが格納されます。config/unicorn.rbapp_path = File.expand_path('../../', __FILE__) worker_processes 1 working_directory app_path pid "#{app_path}/tmp/pids/unicorn.pid" listen "#{app_path}/tmp/sockets/unicorn.sock" stderr_path "#{app_path}/log/unicorn.stderr.log" stdout_path "#{app_path}/log/unicorn.stdout.log" ↓↓↓↓↓↓↓ 以下のように変更 ↓↓↓↓↓↓ # ../が一つ増えている app_path = File.expand_path('../../../', __FILE__) worker_processes 1 # currentを指定 working_directory "#{app_path}/current" # それぞれ、sharedの中を参照するよう変更 listen "#{app_path}/shared/tmp/sockets/unicorn.sock" pid "#{app_path}/shared/tmp/pids/unicorn.pid" stderr_path "#{app_path}/shared/log/unicorn.stderr.log" stdout_path "#{app_path}/shared/log/unicorn.stdout.log"nginxの設定ファイル
同様に、Nginxの設定ファイルも変更が必要です。これまでは/var/www/以下のアプリケーションに対して連携を設定していたので、/var/www/chat-space以下のcurrent、sharedなどのディレクトリと連携するように設定を変更する必要があります。全て消して編集
$ sudo vim /etc/nginx/conf.d/rails.confupstream app_server { # sharedの中を参照するよう変更 server unix:/var/www/<アプリケーション名>/shared/tmp/sockets/unicorn.sock; } server { listen 80; server_name <Elastic IPを記入>; # クライアントからアップロードされてくるファイルの容量の上限を2ギガに設定。デフォルトは1メガなので大きめにしておく client_max_body_size 2g; # currentの中を参照するよう変更 root /var/www/<アプリケーション名>/current/public; location ^~ /assets/ { gzip_static on; expires max; add_header Cache-Control public; # currentの中を参照するよう変更 root /var/www/<アプリケーション名>/current/public; } try_files $uri/index.html $uri @unicorn; location @unicorn { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_redirect off; proxy_pass http://app_server; } error_page 500 502 503 504 /500.html; }各サーバー再起動
$ sudo service nginx reload
$ sudo service nginx restart
$ sudo service mysqld restart
$ ps aux | grep unicorn
$ kill [master number]
$ bundle exec cap production deploy
- 投稿日:2020-04-26T19:52:16+09:00
Rails attr_accessorを使って、より良いコードを書いてみよう。
どうもチャンクノです。
今個人アプリで勝率を表示するページを作っています。
メソッド作成に困リ果てた結果、attr_accessorを使って解決したお話です。
今回は少し長くなります。
初学者の方が見ると参考になる部分があるかもしれません。まずは下記のコードを見てみましょう。
viewの記述 <%= @trade.win_rate(current_user) %>model側の記述 def win_rate(current_user) trades = Trade.where("trades.user_id" => current_user.id) win_trades = trades.where("trades.result" => "勝").count (win_trades / trades.count.to_f * 100).floor endこれで一応勝率が導き出せます。
が!!!
はっきり言ってこれは全然よくないコードです。
なぜだかわかりますか?なぜかというと、月ごとの勝率を出すなど他のパターンが出てきた場合。
メソッド名だけ変えて記述します。 def month_win_rate(current_user) trades = Trade.where("trades.user_id" => current_user.id) win_trades = trades.where("trades.result" => "資産増").count (win_trades / trades.count.to_f * 100).floor endこういう感じでメソッドを作るたびに必ず引数にcurrent_userを取る必要が出てきます。
また、同じ処理を何回も書いてしまう羽目にもなります。
これは保守性に優れていなく、非常によろしくないです。全体の勝率を表示するだけなら10000歩譲っていいかもしれません。
が、自分は月ごとの勝率などを出すことも考えているのでこのままではダメでした。そこで何を使ったかというとタイトルにある通りattr_accessorです。
attr_accessorの内容まで書いてしまうと非常に長くなるのでご自身で調べてみてください?♂️参考までに
https://qiita.com/Hassan/items/0e034a1d42b2335936e6attr_accessorを使った結果先ほどのコードがどのように変化するかというと、、、
controlller def index @trade = Trade.new(current_user_id: current_user.id) endview <%= @trade.win_rate %>model attr_accessor :current_user_id def win_rate (search_win_trades_count / search_user_trades.count.to_f * 100) end def search_user_trades Trade.where("trades.user_id" => current_user_id) end def search_win_trades_count search_user_trades.where("trades.result" => "勝").count endメソッドを作るたびにcurrent_userを引数に取る必要がなくなり、とてもスッキリしましたね。
また、メソッドの処理も別のメソッドに切り分けることで、変更点があっても容易になりました。
同じクラス内にあるメソッドは他のメソッド内でも使うことができるので覚えておくといいと思います。ちなみに初学者の方がこの内容を理解できたら天才だと思います。
そんなものがあるんだな程度で頭の片隅に置いとけば大丈夫です。
では長くなりましたが今日はこの辺で!
皆様よきプログラミングライフを?
- 投稿日:2020-04-26T18:23:16+09:00
I18nについて
I18nとは
国際化という意味で、「Internationalization」の略です。
18の部分は"I"と"n"の間に18文字あることから由来しています。
これを利用することで様々な国の言語に対応させることができます!使い方
tメソッド(tはtranslateの頭文字からきている。)
日本語のアクセスと英語のアクセスに応じて対応可能となる。
<%= I18t("sports.soccer") %>config/locales/ja.ymlja: sports: soccer: "サッカー"config/locales/en.ymlen: sports: soccer: "soccer"lメソッド(Localizeの頭文字である)
lメソッドは日付や時刻を表す際に用います。
config/locales/ja.ymlja: date: formats: default: "%Y/%m/%d" long: "%Y年%m月%d日(%a)" short: "%m/%d" time: formats: default: "%Y/%m/%d %H:%M:%S" long: "%Y年%m月%d日(%a) %H時%M分%S秒 %z" short: "%y/%m/%d %H:%M"実行結果
> I18n.l(Date.today) => "2020/04/26" # 指定がない場合はdefaultを使う > I18n.l(Date.today, format: :short) => "04/26" > I18n.l(Time.now) => "2020/04/26 18:22:54" > I18n.l(Time.now, format: :long) => "2020年04月26日(日) 18時22分54秒 +0900"
- 投稿日:2020-04-26T18:09:41+09:00
Dockerのproduction環境でのbundle exec方法
- 投稿日:2020-04-26T18:09:16+09:00
bundlerバージョン違いのエラーを解消する
Factory Botをインストールしようとしたらエラー。
version
- ruby 2.4.9
- Rails 5.1.1
- factory_bot_rails ~> 4.10.0
bundle install The dependency tzinfo-data (>= 0) will be unused by any of the platforms Bundler is installing for. Bundler is installing for ruby but the dependency is only for x86-mingw32, x86-mswin32, x64-mingw32, java. To add those platforms to the bundle, run `bundle lock --add-platform x86-mingw32 x86-mswin32 x64-mingw32 java`. Fetching gem metadata from https://rubygems.org/............ Fetching gem metadata from https://rubygems.org/. Resolving dependencies... Bundler could not find compatible versions for gem "bundler": In Gemfile: rails (~> 5.1.1) was resolved to 5.1.1, which depends on bundler (< 2.0, >= 1.3.0) Current Bundler version: bundler (2.1.4) This Gemfile requires a different version of Bundler. Perhaps you need to update Bundler by running `gem install bundler`? Could not find gem 'bundler (< 2.0, >= 1.3.0)', which is required by gem 'rails (~> 5.1.1)', in any of the sources. bundler -v Bundler version 2.1.4bundler (< 2.0, >= 1.3.0)が必要なのに2.1.4とバージョンが違うからエラーになるらしい。
# bundlerをインストールできるバージョンを調べる gem search ^bundler$ --all *** REMOTE GEMS *** bundler (2.1.4, 2.1.3, 2.1.2, 2.1.1, 2.1.0, 2.0.2, 2.0.1, 2.0.0, 1.17.3, 1.17.2, 1.17.1, 1.17.0, 1.16.6, 1.16.5, 1.16.4, 1.16.3, 1.16.2, 1.16.1, 1.16.0, 1.15.4, 1.15.3, 1.15.2, 1.15.1, 1.15.0, 1.14.6, 1.14.5, 1.14.4, 1.14.3, 1.14.2, 1.14.1, 1.14.0, 1.13.7, 1.13.6, 1.13.5, 1.13.4, 1.13.3, 1.13.2, 1.13.1, 1.13.0, 1.12.6, 1.12.5, 1.12.4, 1.12.3, 1.12.2, 1.12.1, 1.12.0, 1.11.2, 1.11.1, 1.11.0, 1.10.6, 1.10.5, 1.10.4, 1.10.3, 1.10.2, 1.10.1, 1.10.0, 1.9.10, 1.9.9, 1.9.8, 1.9.7, 1.9.6, 1.9.5, 1.9.4, 1.9.3, 1.9.2, 1.9.1, 1.9.0, 1.8.9, 1.8.8, 1.8.7, 1.8.6, 1.8.5, 1.8.4, 1.8.3, 1.8.2, 1.8.1, 1.8.0, 1.7.15, 1.7.14, 1.7.13, 1.7.12, 1.7.11, 1.7.10, 1.7.9, 1.7.8, 1.7.7, 1.7.6, 1.7.5, 1.7.4, 1.7.3, 1.7.2, 1.7.1, 1.7.0, 1.6.9, 1.6.8, 1.6.7, 1.6.6, 1.6.5, 1.6.4, 1.6.3, 1.6.2, 1.6.1, 1.6.0, 1.5.3, 1.5.2, 1.5.1, 1.5.0, 1.3.6, 1.3.5, 1.3.4, 1.3.3, 1.3.2, 1.3.1, 1.3.0, 1.2.5, 1.2.4, 1.2.3, 1.2.2, 1.2.1, 1.2.0, 1.1.5, 1.1.4, 1.1.3, 1.1.2, 1.1.1, 1.1.0, 1.0.22, 1.0.21, 1.0.20, 1.0.18, 1.0.17, 1.0.15, 1.0.14, 1.0.13, 1.0.12, 1.0.11, 1.0.10, 1.0.9, 1.0.7, 1.0.5, 1.0.3, 1.0.2, 1.0.0, 0.9.26, 0.9.25, 0.9.24, 0.9.23, 0.9.22, 0.9.21, 0.9.20, 0.9.19, 0.9.18, 0.9.17, 0.9.16, 0.9.15, 0.9.14, 0.9.13, 0.9.12, 0.9.11, 0.9.10, 0.9.9, 0.9.8, 0.9.7, 0.9.6, 0.9.5, 0.9.4, 0.9.3, 0.9.2, 0.9.1, 0.9.0, 0.8.1, 0.8.0, 0.7.2, 0.7.1, 0.7.0, 0.6.0, 0.5.0, 0.4.1, 0.4.0, 0.3.1, 0.3.0) # バージョン指定でインストール gem install bundler -v 1.9.9bundler -v Bundler version 2.1.4
バージョンが変わらない?
こうやるとバージョンを指定して、インストールできるらしい。
エラーなくFactory Botをinstallできた。bundle _1.9.9_ install
- 投稿日:2020-04-26T18:01:00+09:00
Ruby on Railsの基礎
rails new
Railsで新規アプリケーションを作成する際に使用。
コマンドを実行する際は作成したいアプリケーション名を最後につけてrails new アプリケーション名とコマンドを実行。
また、オプションを付ける場合にはハイフン-を使い-オプション名と追記することで様々なオプションをつけることができる。$ rails new アプリケーション名 -オプション名 # オプションを付けてアプリケーションを作成MySQL
データを保存するDBの一種。
RailsではMySQLの他に「SQLite」などのDBも使用することができる。
RailsアプリケーションでMySQLデータベースを使用する場合、
rails newコマンドに「-d mysql」というオプションを付けて新規railsアプリケーションを作成する。
このオプションによって「MySQL」というDBに最適化された設定でアプリケーションが生成される。rails _5.2.3_ new app -d mysqlrails db:create コマンド
新しくDBを作成するにはrails db:createというコマンドを実行する。
このコマンドはdatabase.ymlというファイルの内容に基づいてDBを新規作成するという機能を持っている。rails db:createdatabase.yml(データベース・ヤムル) ファイル
database.ymlにはDBの設定を記述する。Railsは運用環境ごとにDBを持つので、運用環境の分だけDBの設定が記述してある。
運用環境
開発を行う際に、運用環境と呼ばれるものを使い分けることで効率的に作業を行うことができる。運用環境には3つの種類があり、以下のような使い分けをする。
・development 開発環境。通常、開発をする際に使用する環境 ・test テスト環境。アプリケーションの動作をテストする際に使用する環境 ・production 本番環境。アプリケーションを実際にリリースする際に使用する環境rails s コマンド
このコマンドをアプリケーションのディレクトリで実行すると、このアプリケーションを動かすためのサーバーが立ち上がる。起動されるこのサーバーは、開発者だけがPC上でアプリを利用するためのものであり、ローカルサーバーと呼ぶ。
# ローカルサーバーを起動 $ rails sControl + Cコマンド
サーバーを停止する。
localhost:3000
localhostとは「自分のPC」という意味。自分のPC内にサーバーを立ち上げる。
- 投稿日:2020-04-26T17:58:35+09:00
「data()」と「attr()」について
背景
カスタム属性を使う際に必須のメソッドの2つの違いがいまいち理解していなかったため調べて自分なりにまとめてみた。
data()について
「data()」を使うとHTML要素内に付与されたdata属性に対して、取得・設定・変更などが簡単に行える。
独自の属性を作成して付与できるのがdata属性の特徴です。
このようにすることで、あとからJavaScriptやjQueryで取得・変更できるわけです。attr()について
dataメソッドと似ていますが、属性名の指定は「data-」の部分も一緒に記述しなければならない。
data()の使い方
<body> <p data-name="sato" data-age="42" data-tel="012-3456-7890">私の名前は佐藤です</p> <script> const result = $('p').data(); console.log( result ); </script> </body> // =>{name: "sato", age: 42, tel: "012-3456-7890"}対象要素.data( 属性名, 値 )とすると設定・変更できる
<body> <p>おはよう</p> <script> $('p').data('greet', 'morning'); console.log( $('p').data('greet') ); // 属性の設定 $('p').data('greet', 'hello'); console.log( $('p').data('greet') ); // 属性の更新 </script> </body> // => morning // => eveningattr()の使い方
対象要素.attr( 属性名, 値 )
<body> <p>おはよう</p> <script> $('p').attr('data-greet', 'morning'); </script> </body> // => morning違いは?
「attr()」で設定した属性はHTML要素へ直接追加されるが、「data()」で設定した属性はjQuery内へ一時的に保持されるだけで直接HTML要素に追加されるわけではない。
<body> <p id="one">テスト1</p> <p id="two">テスト2</p> <script> $('#one').attr('data-name', 'sato'); console.log( $('#one')[0] ); $('#two').data('name', 'sato'); console.log( $('#two')[0] ); </script> </body> // => <p id="one" data-name="taro">サンプルテキスト</p> ←追加されている // => <p id="two">サンプルテキスト</p> ←追加されていない
- 投稿日:2020-04-26T17:53:27+09:00
Rails で render の後に書かれた処理は実行されるけどレスポンスを返すのは全処理が終わった後
背景
- こちらの記事を読んで Rails で response を返した後の処理が実行されるのかが気になった
- アクションの中のrender(), redirect_to()の後の処理は実行される
- 書かれたのが10年以上前だったので最近だとどうなのかを調べたい
- 先に response を返せると何が嬉しいか?
- タイムアウトまでの時間制限が厳しいシステムや機能と連携する際に非同期処理にしなくてもよくなる
- 例えば Slack とか
- https://api.slack.com/interactivity/slash-commands#responding_to_commands
This confirmation must be received by Slack within 3000 milliseconds of the original request being sent, otherwise a Timeout was reached will be displayed to the user.
環境
➜ ruby -v ruby 2.7.0p0 (2019-12-25 revision 647ee6f091) [x86_64-darwin19] ➜ rails -v Rails 6.0.2.2調べた結果
- 普通にタイムアウトした
![]()
render
head
などのレスポンス系のメソッドの後に書かれた処理も実行される- ただ、アクションの中で書かれたすべての処理が実行された後に response を返すっぽい
- 処理の順番が逆になるわけではないので最後に render するのが自然
class HelloController < ApplicationController def hello render status: 200 sleep 3.0 slack_client = Slack::Web::Client.new( token: ENV['SLACK_TOKEN'] ) res = slack_client.chat_postMessage( channel: params[:channel_id], text: 'hello world' ) end end
after_action
系を使っても同じ挙動class HelloController < ApplicationController after_action :slack_post def hello render status: 200 end def slack_post sleep 3.0 slack_client = Slack::Web::Client.new( token: ENV['SLACK_TOKEN'] ) res = slack_client.chat_postMessage( channel: params[:channel_id], text: 'hello world' ) end end
- ただ
before_action
で render すると処理がそこで終わるclass HelloController < ApplicationController before_action :before_render def before_render render status: 200 end def hello # ここは実行されない sleep 3.0 slack_client = Slack::Web::Client.new( token: ENV['SLACK_TOKEN'] ) res = slack_client.chat_postMessage( channel: params[:channel_id], text: 'hello world' ) end end
- 投稿日:2020-04-26T16:50:56+09:00
bundle installでAn error occurred while installing mysql2
$ rails _5.2.4.1_ new appname --database=mysql --skip-test --skip-turbolinks --skip-bundleでrailsアプリを新規作成した後、
$ bundle install ... ----- Don't know how to set rpath on your system, if MySQL libraries are not in path mysql2 may not load ----- ----- Setting libpath to /usr/local/Cellar/mysql/8.0.19/lib ----- ... ld: library not found for -lssl clang: error: linker command failed with exit code 1 (use -v to see invocation) make: *** [mysql2.bundle] Error 1 make failed, exit code 2 Gem files will remain installed in /Users/machoair/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/gems/mysql2-0.5.3 for inspection. Results logged to /Users/machoair/.rbenv/versions/2.6.1/lib/ruby/gems/2.6.0/extensions/x86_64-darwin-17/2.6.0/mysql2-0.5.3/gem_make.out An error occurred while installing mysql2 (0.5.3), and Bundler cannot continue. Make sure that `gem install mysql2 -v '0.5.3' --source 'https://rubygems.org/'` succeeds before bundling.のエラーが発生
解決策
上記の通り、エラー内容は
Don't know how to set rpath on your system, if MySQL libraries are not in path mysql2 may not load Setting libpath to /usr/local/Cellar/mysql/8.0.19/lib ld: library not found for -lssl私もよく理解していませんが、「libssl.dylib」を探そうとして、「/usr/local/Cellar/mysql/8.0.19/lib」を探したがありませんというエラーらしいです。
【Rails】MySQL2がbundle installできない時の対応方法
https://qiita.com/fukuda_fu/items/463a39406ce713396403の記事を参考に、
$ cd アプリ場所 $ brew info openssl ... For compilers to find openssl@1.1 you may need to set: export LDFLAGS="-L/usr/local/opt/openssl@1.1/lib" #ここを参考に次のコマンドを書く export CPPFLAGS="-I/usr/local/opt/openssl@1.1/include" #ここを参考に次のコマンドを書く ... $ bundle config --local build.mysql2 "--with-cppflags=-I/usr/local/opt/openssl@1.1/include" $ bundle config --local build.mysql2 "--with-ldflags=-L/usr/local/opt/openssl@1.1/lib" You are replacing the current local value of build.mysql2, which is currently "--with-cppflags=-I/usr/local/opt/openssl@1.1/include" $ bundle installで解決しました!
- 投稿日:2020-04-26T16:30:10+09:00
【Rails】has_secure_passwordでパスワードのセキュリティを強化
目的
パスワードのセキュリティを強化する。
手段
has_secure_passwordを使ってパスワードをハッシュ化する。
・ハッシュ化は、訳のわからない暗号みたいな文字列に変換すること。
・has_secure_passwordでハッシュ化されたパスワードは、同じ文字列で生成すれば常に同じ値になるので一致しているかどうかをチェックする際に使える。
・has_secure_passwordでハッシュ化したパスワードは、元のパスワードそのものに戻すことができないので、ハッシュ化されたパスワードを奪われたとしても何の問題もないのでパスワードのセキュリティが強固になる。
手順
1.Userモデル作成時のパスワード属性をpassword_digestとする。
➡︎has_secure_passwordを使う際の命名規則なので必須。
2.Gemfileにbcryptというgemを追加して、インストールする。
➡︎bcryptというgemをインストールすることで、has_secure_passwordを使えるようになりパスワードをハッシュ化できるようになる。
➡︎$ bundle installコマンドを忘れずに。3.Userモデルにhas_secure_passwordを記述。
➡︎Userモデル内にhas_secure_passwordを記述したことにより、password属性とpassword_confirmation属性の2つの属性が追加される。データベースのカラムとは対応していない属性。
➡︎どういうことかというと、この2つはユーザーに入力を求めるためだけの属性で、
この2つの属性をユーザーに入力させる
ことで、Railsはこの2つの一致をチェック
した後、一致していたらそのパスワードをハッシュ化
してデータベースのpassword_digest属性に格納される
ようになっている。以上の記述を行うことで、ユーザーの新規登録時に入力したパスワードはハッシュ化されるようになる。
ターミナル$ rails g model user ... ... password_digest:stringdb/migrate/[timestamps]_create_users.rbclass CreateUsers < ActiveRecord::Migration[5.2] def change create_table :users do |t| . . . t.string :password_digest . . . end end endターミナル$ rails db:migrateGemfilegem 'bcrypt', '~> 3.1.7'ターミナル$ bundle installapp/models/user.rbclass User < ApplicationRecord has_secure_password . . . end
試しにコンソールで確認してみる。$ rails c --sandbox > user = User.new(..., password: '123456', password_confirmation: '123456') > user.save => true >user.password_digest => 'fflafbnalwefhhhawkleufhb'ユーザーにpasswordとpassword_confirmationに任意の値を入力させれば、2つの属性が一致しているかどうかを検証した後に、ちゃんとハッシュ化されたパスワードがpassword_digest属性に保存されている事がわかる
参考
- 投稿日:2020-04-26T13:53:31+09:00
chmod 600 ←600ってなんやねん
近況報告
とりあえずデプロイは完了しました。readmeを書いて,投稿物を揃え,エラー対応すれば見世物としての体裁はできあがるのかな。某雑食系さんのツイートに,ポートフォリオはサーバーサイドの実力はもちろんのこと,コンテンツ力,そして見た目も評価の対象になりうるとありましたね(めっちゃ噛み砕いた)。自分のはサーバーサイドの記述,実力はまだまだですけど,見た目は手を抜かなければよくできるので,今の自分の最善を尽くした作品を作っていこうと思います。
今回の目的
chmodに続く数字を知る。
結論
ファイルへの権限の種類だよ
詳細
chmodは「change mode」の略で,桁数,数字の組み合わせによって編集の権限とかを設定しています。
これにより,第三者からの不正アクセスの予防に繋がります。
桁数 意味 1桁目(百の位) 所有者のアクセス権限の範囲 2桁目(十の位) グループのアクセス権限の範囲 3桁目(一の位) その他のユーザーのアクセス権限の範囲
数字 意味 4 読み出し許可 2 書き込み許可 1 実行許可 0 権限なし 数字の足し算で権限は増えていきます。例えば全ての権限なら
4+2+1+0で7に
読み出しと書き込みだけなら4+2で6になります。
このように編集できるユーザーを適宜設定できます。おわりに
Linuxのコマンドは他にもごっそりあるのでそれの一部と考えていただければ。
微量でも参考になったらLGTM,ご指導はコメント欄にお願いします!
- 投稿日:2020-04-26T13:50:02+09:00
なぜany?はpresent?より高速と言われるのか
はじめに
「present?メソッドとany?メソッドだったらany?メソッドが高速なのか・・・なぜだろう?」
この疑問を解決すべく、present?メソッドとany?メソッドの処理の違いについて調べてみました。環境
macOS Catalina Version 10.15.4
Ruby: 2.7.0
Ruby on Rails: 6.0.2.2present?メソッド、any?メソッドの違い
どちらもテーブルにデータが存在するかを確認するメソッドです。
けれども内部処理はどちらも異なっています。侍エンジニアブログさんの、any?メソッド記事の一部を抜粋します。
present?メソッドとany?メソッドとの違いについて紹介します。
結論からいうとany?メソッドの方が高速です。
present? → 全てのデータを取得する
any? → 1件のみデータを取得する
Railsが実行する
SQLを比較して違いを確認してみましょう。> Sample.where(name:"侍1").present? Sample Load (0.4ms) SELECT `samples`.* FROM `samples` WHERE `samples`.`name` = '侍1' => true > Sample.where(name:"侍1").any? Sample Exists (0.4ms) SELECT 1 AS one FROM `samples` WHERE `samples`.`name` = '侍1' LIMIT 1 => trueこのように、SQLの最後にLIMIT 1 が付与されています。
any?メソッドがpresent?よりも優れているように見えます。
ではなぜこのような処理になっているのか、Ruby on Railsのコードを追ってみました。なお、modelは侍エンジニアブログさんと同様のSampleモデル(stringのname属性のみ)を作成しています。
present?メソッドの内部処理
present?メソッド実行時のコードの場所はblank.rbとなっています。
このコードを追ってみます。>Sample.where(name: "侍1").method(:present?).source_location => ["/Users/xxxxx/.rbenv/versions/2.7.0/lib/ruby/gems/2.7.0/gems/activesupport-6.0.2.2/lib/active_support/core_ext/object/blank.rb", 25]blank.rbdef present? !blank? endrelation.rbalias :loaded? :loaded def initialize(klass, table: klass.arel_table, predicate_builder: klass.predicate_builder, values: {}) @klass = klass @table = table @values = values @offsets = {} @loaded = false @predicate_builder = predicate_builder @delegate_to_klass = false end def records # :nodoc: load @records end def load(&block) unless loaded? @records = exec_queries(&block) @loaded = true end self end def blank? records.blank? endよってpresent?メソッドを呼び出した場合、クエリ未発行ならば、exec_queryメソッドでクエリを発行します。
このクエリは、指定されたテーブルの全レコード検索となります。
その後、結果に応じてblank?を行います。
もしクエリ発行済であれば、クエリを発行せずにblank?を行います。any?の内部処理
any?メソッド実行時のコードの場所はrelation.rbとなっています。
このコードを追ってみます。>Sample.where(name: "侍1").method(:any?).source_location => ["/Users/xxxxx/.rbenv/versions/2.7.0/lib/ruby/gems/2.7.0/gems/activerecord-6.0.2.2/lib/active_record/relation.rb", 277]relation.rbdef empty? return @records.empty? if loaded? !exists? end def any? return super if block_given? !empty? end def load(&block) unless loaded? @records = exec_queries(&block) @loaded = true end self endfinder_method.rbdef exists?(conditions = :none) if Base === conditions raise ArgumentError, <<-MSG.squish You are passing an instance of ActiveRecord::Base to `exists?`. Please pass the id of the object by calling `.id`. MSG end return false if !conditions || limit_value == 0 if eager_loading? relation = apply_join_dependency(eager_loading: false) return relation.exists?(conditions) end relation = construct_relation_for_exists(conditions) skip_query_cache_if_necessary { connection.select_one(relation.arel, "#{name} Exists?") } ? true : false endよってany?メソッドを呼び出した場合、毎回exists?メソッドにて、テーブルにレコードが1件あるかどうかクエリを発行します。
その後、結果を確認しています。
もしload変数がtrueになった場合は、クエリ発行せずに結果を確認するのみとなります。まとめ
最初に記載した疑問の答えです。
any?メソッドがpresent?よりも優れているように見えます。
ではなぜこのような処理になっているのか、Ruby on Railsのコードを追ってみました。present?メソッドの場合、初回のみ全レコードを取得するクエリを発行して判定します。
2回目以降の呼び出しはクエリを発行せずに判定します。any?メソッドの場合、基本的に毎回、テーブルから1件レコードを取得するクエリを発行して判定します。
このため、全レコードを取り出さないany?メソッドが高速と言われているだと思われます。
ご指摘等あればコメントにご記載をお願い致します。
参考記事
【Rails入門】any?メソッドの便利な使い方を紹介
RailsのActiveRecord::FinderMethodsのSQLクエリ発行の有無について調べる
ActiveRecord::QueryMethodsのselectメソッドについて深掘りしてみた
週刊Railsウォッチ(20191216前編)Rails 6.0.2がリリース、平成Ruby会議01開催、古いRailsのfindメソッド置き換えほか
RailsのArelを調査してみた
- 投稿日:2020-04-26T13:41:35+09:00
AWS Cloud9でRuby on Railsを動かしてみた
こんにちは!モリタケンタロウです!
今回はAWSのCloud9で、Ruby on Railsを動かす方法について紹介します。AWS Cloud9とは
AWS Cloud9については↓をご参考にどうぞ
Ruby on Railsとは
Ruby on RailsはRubyで動作するMVCモデルのフレームワークです。
Webアプリケーション開発に向いていて、世の中のあらゆるサービスがこのRuby on Railsでできています。
Railsはオワコンと言われていたりもしますが、僕が会社でRailsのWebアプリ開発をやっていたときに、勉強しやすくて書きやすかったので、とりあえず今回はRailsを使ってみようと思います。とにかくやってみよう!
AWS Cloud9では最初からRubyもRailsもインストールされています。
ruby -v
とrails -v
のコマンドで確認できます。
確認できたら早速アプリを作成してみましょう。
rails new [アプリ名]
コマンドで作ります。
そうすると、指定した名前のアプリのディレクトリが作成されました!
作ったアプリのディレクトリの中に入って、rails server
コマンドでアプリを動かしてみましょう。
動いている様子は、Preview > Preview Running Application で確認できます。
上手くいくと、こんな画面が出てきます。めでたしめでたし!
上手くいかないと、こんな画面が出てくるかもしれません。
そんなときは、↓を参考にしてみてください。ちょっとつまづきながらも無事に「Yay!…」という画面が出せたので、これからコツコツRails開発を始めていきます!
それでは~
- 投稿日:2020-04-26T13:40:32+09:00
Railsで新しいアプリを作ったらActiveRecord::ConnectionNotEstablishedが出てきた
こんにちは!モリタケンタロウです!
今回はRailsでアプリを新規作成して動かしてみたら、「ActiveRecord::ConnectionNotEstablished」というエラーが出てきたので、それを解決する方法について紹介します。開発環境
- ruby 2.6.3p62
- Rails 5.0.0
エラー内容
rails server
コマンドでアプリを動かすと、画面にはこんなエラーが出てきます。
ActiveRecord::ConnectionNotEstablished
No connection pool with id primary found
なにこれ!?分からん…
ということでググると、RailsのORM機能であるActiveRecordが、sqlite3
の新しいバージョンに対応してないことが原因らしい。(参考:ActiveRecord::ConnectionNotEstablished No connection pool)対処内容
ということで、Railsがインストールしているパッケージを管理しているGemfileを編集します。
gem 'sqlite3', '~> 1.3.6'Gemfileを編集したら、
bundle install
コマンドでインストールパッケージを更新します。
そしてrails server
コマンドでアプリを起動すると…
見事、アプリが正常に起動しました。めでたしめでたし!
ということで一件落着(^^)
それでは~
- 投稿日:2020-04-26T13:18:50+09:00
【環境構築】Rails6をCloul9で環境構築する
Rails6をCloud9で動かす
試行錯誤を繰り返したが構築できなかったため、cloud9の作成からやり直しました。
その経緯を着ていきます。
- 環境の作成
以下の記事を参考にしました。
https://skillhub.jp/courses/134/lessons/785設定画面内の「Rails6ではこちら」が重要かと思います。
- サーバーが立ち上がらない
以上の記事の通り進めましたが、以下のエラーメッセージが出て立ち上がらない。
qiita.rbAddress already in use - bind(2) for "127.0.0.1" port 8080(Errno::EADDRINUSE)色々と調べ、以下のように試行錯誤。
qiita.rb$ lsof -i:8080 COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME ruby 8850 ubuntu 14u IPv4 42953 0t0 TCP localhost:http-alt (LISTEN) ruby 8850 ubuntu 15u IPv6 42954 0t0 TCP ip6-localhost:http-alt (LISTEN)と表示され、8850の部分をkillすればいいらしく、下記を実行。
qiita.rb$ kill -9 8850 $ lsof -i:8080サーバーが立ち上がりました!!
- 投稿日:2020-04-26T13:10:22+09:00
【Rails】モデルのオブジェクト生成に対する制限・制御を行ってくれる機能
はじめに
備忘録
目的
データベースに不正なデータが保存されないようにすること。
手段
1.データベースカラムに対して制御を記述する。
2.モデルに対して検証を記述する。両者の違い
データベースカラムに対する制御
➡︎一意性の検証➡︎ユーザーへエラーメッセージを届けられない
➡︎モデルでは弾けないような、直接データベースに他のシステムから操作を加える作業に対しての制御
モデルに対する検証
➡︎データベースでは制御しきれない部分の補完➡︎ユーザーへエラーメッセージを届ける事ができる
※今回は、制御に関する機能の説明のみです。
1.データベースカラムへの制御でよく行われる方法4つ
※データベースカラムへの制御はマイグレーションファイルに記述していくこと。
1.データ型を付与する。
➡︎データ型を付与する事で、そのデータ型以外のデータが格納されることを阻止する。
→例えば、「名前カラムには文字列しか格納させたくない」場合には、名前カラムに文字列のデータ型を付与すると良い。2.NOT NULL制約を付与する。
➡︎カラムに対して、必ず何かしらの値が格納されるようにしたい場合に空の値が格納されることを阻止する。
→例えば、ユーザーが新規登録する際に「名前が空のまま保存されることを阻止したい」場合には、この制約を追加すると良い。3.文字列の長さを制御する。
➡︎カラムに対して、文字列の長さを指定することで指定した文字列以上の長さのデータが格納されることを阻止する。
→例えば、ユーザーが新規登録する際に「名前が20文字以上になることを阻止したい」場合には、文字列の長さを制御してあげると良い。4.ユニークインデックスを付与する。
➡︎カラムに対して、ユニークインデックスを付与する事でそのデータの一意性が確保され、同じデータが格納されることを阻止する。
→例えば、ユーザーが新規登録する際に「メールアドレスが他のユーザーと被ることを阻止したい」場合には、メールアドレスカラムに対してユニークインデックスを付与してあげると良い。コマンドを実行してモデルのクラスファイル(マイグレーションファイル)を作成 $ rails g model Userdb/migrate/[timestamps]_create_users.rbclass CreateUsers < ActiveRecord::Migration[5.2] def change create_table :users do |t| t.string :name, limit: 20, null: false t.string :email, null: false t.timestamps t.index :email, unique: true end end endマイグレーションファイルに変更を加えたらデータベースに変更を保存する $ rails db:migrate
t.string :name
➡︎データ型の付与
limit: 20
➡︎文字列の長さを制御
null: false
➡︎NOT NULL制約(SQLのnullとRubyのnilを混同させないこと)
t.index :email, unique: true
➡︎ユニークインデックス付与で一意性確保
2.モデルに対する検証方法は主に2つ
※モデルに対する検証はモデルファイルに記述していくこと。
※モデルに対する検証の仕組みは「検証結果が不正だった場合は、エラーメッセージを生成する」であることに注意。なので、例えばユーザーに新規登録をさせる場合は「検証で失敗した結果、何が原因で登録できなかったのかをユーザーに知らせる」事が目的。1.Railsであらかじめ用意されている、検証用のヘルパーメソッドを使う。
➡︎モデルに対して、validatesオプションを使って検証したいヘルパーメソッドを適用させることで、メソッドの内容に準じて検証を行う事ができる。
→例えば、ユーザーが新規登録する際に「名前未入力による登録する事を阻止したい」場合には、validatesオプションに対してそれ用のヘルパーメソッドを適用させる。
→その他にもたくさんの検証ヘルパーが用意されている。2.検証用のメソッドを自分で定義しちゃう。
➡︎モデルに対して、「どんな検証を行いたいか」「どんなエラーメッセージを表示させたいか」を考えてメソッドを定義していく。
→例えば、ユーザーが新規登録する際「名前にハイフンを入れる事を阻止したい」ときには「名前にハイフンを含ませた場合、"名前にハイフンを入れることはできません"というエラーメッセージを生成する」といったメソッドを定義すれば良い。➡︎メソッドを定義したら、validate(単数形であることに注意)オプションに適用させる。
app/models/user.rbclass User < ApplicationRecors validates :name, presence: true validate :validate_name_not_include_hyphen def validate_name_not_include_hyphen errors.add(:name, 'にハイフンを入れる事はできません') if name&.include?('-') end end
validates :name, presence: true
➡︎Userモデルのname属性の値が入力されていることをチェックする。
validate_name_not_include_hyphen
➡︎メソッド名。
errors.add(:name, 'にハイフンを入れることはできません') if name&.include?('-')
➡︎名前にハイフンが含まれていた場合、「(名前)にハイフンを入れることはできません」というエラーメッセージを生成する。➡︎nameに「&」を付けているのは、名前がnilだった場合に例外を発生させないため。nilだった場合はnilを代入させることができる。そうすることでvalidatesオプションのpresence: trueで検証させる。
※エラーメッセージを表示させるまでがゴール
エラーメッセージを生成・表示させるには(ユーザー新規登録を例にする)
1:新規登録ならユーザーコントローラのcreateアクション内で、送信されてきたデータからオブジェクトを
@user.save
メソッドで保存・更新する作業を行ってあげる。
➡︎ビューで再利用するためにインスタンス変数でオブジェクトを定義してあげること。2:不正なデータが送信された場合は、saveメソッドの効果により検証が実行され保存されずにfalseを返し、errorsという配列に保存に失敗したオブジェクトが格納される。
➡︎saveメソッドやupdate_attributesメソッドなど保存・更新時に検証を行ってくれるメソッド
を適用させないと、検証を実行してくれないので注意。
➡︎例えば、ユーザーが名前を空のまま保存したとしたら@user.errorsの配列には「@messages ={:name=>["を入力してください"]}
」という旨のエラーメッセージが格納される。3:
@user.errors.full_messages
と記述することで、errors配列に格納されているエラーメッセージを取得できる。
➡︎名前を入力してください
4:取得した上記のエラーメッセージをビューで表示することで、ユーザーにエラーメッセージを届ける事ができるようになる。
以上の手順を踏む必要がある。
参考
- 投稿日:2020-04-26T13:01:26+09:00
Heroku+Rails+MySQLでデプロイする方法
Heroku+Rails+MySQLでデプロイした際の備忘録として作成いたしました。
環境
MacOS 10.15.4
Ruby 2.5.1
Rails 5.2.3
Mysql2 0.5.3Heroku上にアプリを作成
※Herokuの新規登録とクレジットカードの登録がまだの方は登録を済ませてから行ってください。
$ heroku login上記のコマンドでブラウザにログインページが出てくるのでログインしてください。
$ heroku create <アプリ名>$ git remoteherokuのgit URLが表示されることを確認してください。
下記の様に出力されます。heroku https://git.heroku.com/<アプリの名前>.git (fetch) heroku https://git.heroku.com/<アプリの名前>.git (push) origin git@github.com:shou1012/<アプリの名前>.git (fetch) origin git@github.com:shou1012/<アプリの名前>.git (push)git remoteで表示されたherokuのgit URLをリモートリポジトリに追加します。
$ git remote add heroku https://git.heroku.com/xxxxx-xxxxx-xxxxx.git環境設定
データベースと環境変数の設定を行なっていきます。
今回は無料のigniteプランで作成致します。$ heroku addons:create cleardb:ignite$ heroku config下記の様にClearDBのURLが表示されますので、コピーしておきます。
CLEARDB_DATABASE_URL: mysql://<ユーザー名>:<パスワード>@<ホスト名>/<データベース名>?reconnect=true上記のURLを参考に下記を登録していきます。
$ heroku config:add DB_NAME='<データベース名>' $ heroku config:add DB_USERNAME='<ユーザー名>' $ heroku config:add DB_PASSWORD='<パスワード>' $ heroku config:add DB_HOSTNAME='<ホスト名>' $ heroku config:add DB_PORT='3306'続いて、DATABASE URLを登録します。
※今回はmysql2で登録しますが、Gemfileを確認して'mysql'を使用している場合は、mysql://で始めてください。$ heroku config:add DATABASE_URL='mysql2://<ユーザー名>:<パスワード>@<ホスト名>/<データベース名>?reconnect=true'Railsの環境変数にcredentials.yml.encを使っている場合は下記で登録できます。
$ heroku config:set RAILS_MASTER_KEY='cat config/master.key'heroku configで登録内容が確認できます。
$ heroku config本番環境のcompileの設定
config/environments/production.rbに下記を追加します。
config/environments/production.rb
config.assets.compile = true #falseからtrueへ config.assets.initialize_on_precompile=falseデプロイ
$ git add .$ git commit -m "コミットメッセージ"$ git push heroku masterこれでうまくいけばデプロイは完了です!!
エラーが出る場合はこちらをご確認ください。最後にdbマイグレーションをします。
$ heroku run rake db:migrateでは、アプリを開いてみましょう!
$ heroku open以上でHerokuによるデプロイが完了しました!
最後に
Herokuを使うことで非常に簡単にデプロイができました。
問題がなければこれからも使用していきたいです。参考
https://kurose.me/heroku-deploy/
https://qiita.com/rainbow___0/items/1789920cf797b5e80a5e
https://qiita.com/daigou26/items/64d87d987652c4108ae6
https://qiita.com/terufumi1122/items/27bf288414569e13e050
- 投稿日:2020-04-26T12:40:51+09:00
AWSを用いてrailsアプリをデプロイするプロセスを頑張って噛み砕いてみるvol.6
近況報告
大海に糸を垂らして魚を釣るのと鱒がそこにいるとわかっている生簀で鱒を釣るの,どちらが先に釣れるでしょうか。価値があるから売れるのと,売れるから価値がある,どちらが始まりなのでしょうか。鶏と卵論争ではないけれども,考えていくべきことですよね。
ついに最後,Nginxですね。
まだやりたいことはあって,予定ではCapistranoとベーシック認証があるのでvol.8以上あるのか笑
さあいってみようかぁ!今回の内容
・インフラ整備での各アクションの言語化
・コードを単に打っているだけでは理解しきれないし,他に応用できないので言語化して整理
・テックキャンプ受講生支援()大まかな流れ&設定
Nginxインストール
事前準備
Nginxインストール&設定
EC2.sudo yum -y install nginxsudo yum の解説は前の項で触れています。
インストールできたら設定を編集していきます。むやみやたらにいじられたくないファイルなので権限も強いです。sudo権限でvim形式で編集していきます。EC2.$ sudo vim /etc/nginx/conf.d/rails.confrails.confupstream app_server { server unix:/var/www/<アプリケーション名>/tmp/sockets/unicorn.sock; } ⇨Unicornと連携させるための設定。アプリケーション名を自身のアプリ名に書き換えることに注意。upstreamは上流の意。ここでunixが登場していることはよくわかんなかった。 server { ⇨ {}で囲った部分をブロックと呼ぶ。サーバの設定ができる listen 80; ⇨このプログラムが接続を受け付けるポート番号 server_name <Elastic IP>; ⇨接続を受け付けるリクエストURL client_max_body_size 2g; ⇨クライアントからアップロードされてくるファイルの容量の上限を2ギガに設定。デフォルトは1メガ root /var/www/<アプリケーション名>/public; ⇨接続が来た際のrootディレクトリ location ^~ /assets/ { ←assetファイルはここに入っているのを参照するよ gzip_static on; ←圧縮状態のものを配信。容量が小さくなるのでメモリの負担減らせる expires max; ←キャッシュの有効期限。maxは限界までの意 add_header Cache-Control public; ←キャッシュを受け取る範囲の選択 ⇨assetsファイル(CSSやJavaScriptのファイルなど)にアクセスが来た際に適用される設定 } try_files $uri/index.html $uri @unicorn; ⇨ファイルの選択,右の$からアクセスされる location @unicorn { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_redirect off; proxy_pass http://app_server; ⇨Nginxからユニコーンにむけた設定 } error_page 500 502 503 504 /500.html; ⇨エラーが表示された時のページ }と<アプリケーション名>計三箇所直したら,脱出(:wq)
補足
プロキシ
ブラウザとウェブサーバーの中間役。ウェブサーバーの情報をブラウザで写すが,プロキシはウェブサーバーの代理としてウェブサーバーからの情報を写す。 ⇨わかりやすかった説明
location unicornではHTMLメソッドの受け取る方法とか表示の仕方とか設定してるっぽい。権限変更を行ったあと,再起動をします。
EC2.$ cd /var/lib $ sudo chmod -R 775 nginx ←-RはNginxに対してって意味 $ cd ~ $ sudo service nginx restart ⇨初めにfailed出ても再起動でOKがでれば大丈夫カリキュラムで分からなかった点
POSTメソッドを用いるとエラーが発生する可能性があるから権限変更を行うらしいのですが,このコマンドが通信量の多いPOSTメソッドのエラーを防ぐのかまだ理解できていません。●補足chmodについて
UnicornをNginxに接続
config/unicorn.rblisten 3000 ↓以下のように修正 listen "#{app_path}/tmp/sockets/unicorn.sock"githubに反映後,EC2に読み込み。
unicorn再起動処理をして,ブラウザにElastic IPを直打ちしてアプリケーションのルートページが表示できれば成功。うまく表示できない場合はもう一回やり方を見直す。URLが見つからないことで表示されてない可能性があるので注意して見る。終わりに
テックキャンプのカリキュラム,はしょりすぎぃ!!!
まあ多分目的は完全理解というより大枠を捉えよ的な教科書みたいなアプローチですな。
10週間でやれることなんてたかがしれてるし,Nginxひとつとっても理解しようとすれば数百ページの本を読まないとだから無難なのかな(しかもオープンソースだから今この瞬間にアップデートされているかもしれない...)。微量でも参考になったらLGTM,ご指導はコメント欄にお願いします!
- 投稿日:2020-04-26T12:34:09+09:00
【Rails】Could not find a JavaScript runtime となる時の解決方法
【事象】
bundle exec rake db:create すると下記のエラーが出る。rake aborted!
ExecJS::RuntimeUnavailable: Could not find a JavaScript runtime.
See https://github.com/rails/execjs for a list of available runtimes.【解決策】
Gemfileに下記を追加し、bundle installすると解決した。
ExecJSとは、RubyからJavaScriptコードを実行できるもの。
エラーの原因は、RubyからJavaScriptを呼び出す役割を持つ
ExecJSのランタイムが見つからないためのようなのでランタイムを追加してあげれば良いと推測。ExecJSのことを https://github.com/rails/execjs
で見たが、gem therubyracerをインストールするとエラーになったので
また調べてgem mini_racerをインストールすると解決した。
- 投稿日:2020-04-26T10:52:50+09:00
[rails] migrate:reset でのエラー
はじめに
railsでアプリを作成していた際、db:migrateをした際に、エラーが発生しめmigrate:resetをしたのですがその際初めてのエラーが発生したので、その備忘録として書きたいと思います。
最初のエラー
新しくテーブルを作成するためにマイグレーションファイルを編集して実行したところファイル内に記述していたテーブル名に記述ミスがあり、エラーが発生しました。
class CreateHoges < ActiveRecord::Migration[5.2] def change create_table :hoges do |t| t.references :huge t.text :text t.timestamps end add_foreign_key :hoges, :missname, column: :huge_id # missnameが記述ミス end endそのため、記述を直し改めてマイグレーションファイルを実行したところ以下のエラーが発生しました。
rails aborted! StandardError: An error has occurred, this and all later migrations canceled: SQLite3::SQLException: table "hoges" already exists: CREATE TABLE "hoges"どうやらテーブルは既に存在しているといって、エラーが起きているようです。
まさかと思いテーブルを確認しても出来ていません。
rails db:migrate:status で確認してもステータスは downになっていました。原因
どうやらmigrationの際に、処理が途中まで進んで、残りでエラーが起きているときは、テーブルは生成されているけれどもテーブルを生成したmigrationは未実行のステータスになっていることがあるようです。
(create_tableのあと、add_foreign_keyしたところにエラーがあって、というパターン)migrate:reset
ならば、一度データベースを全て削除した上で、再度実行したら直りそうです。
以下のコマンドを実行rails db:migrate:resetそしたら、またもやエラー
rake aborted! ActiveRecord::NoEnvironmentInSchemaError: Environment data not found in the schema. To resolve this issue, run: bin/rails db:environment:set RAILS_ENV=developmentなんだこれは、と思い調べたところ、どうやら指示されるようにコマンドを入力したら直りそうです。
以下の記事が、とても参考になります。
ActiveRecord::NoEnvironmentInSchemaErrorについて解決
まず指示されるまま以下のコマンドを実行
rails db:environment:setそして、再度以下のコマンドを。
rails db:migrate:resetようやく正常にテーブルを作成することができました。
おわり
今回はmigrate:resetで解決しましたが、もし他のテーブルに影響を与えない方法があるならば、教えていただければ幸いです。
最後まで読んでいただき、ありがとうございました。
- 投稿日:2020-04-26T09:46:38+09:00
【Rails】wheneverを用いたバッチ処理の実装
目標
登録ユーザー全員に、Googleメールを1日毎に送信する。
開発環境
・Ruby: 2.5.7
・Rails: 5.2.4
・Vagrant: 2.2.7
・VirtualBox: 6.1
・OS: macOS Catalina前提
・メール送信機能を実装済み。
メール送信機能 ➡︎ https://qiita.com/matsubishi5/items/c88e8c58b1ce39302868
メール送信機能を編集
1.
「login_mailer.rb」
を編集daily_mailer.rbclass DailyMailer < ApplicationMailer def send_mail(user) @user = user mail to: @user.email, subject: "定期配信" end def self.send_when_everyday @users = User.all @users.each do |user| DailyMailer.send_mail(user).deliver end end end2.
「send_when_login.html.erb」
を編集daily_mailer/send_mail.html.erb<%= @user.name %> 様 <p>定期配信メールです。</p>3.
「application_controller.rb」
を編集application_controller..rb#コメントアウト又は削除 def after_sign_in_path_for(resource) LoginMailer.send_when_login(current_user).deliver root_path endバッチ処理を実装
1.
Gem
を追加Gemfilegem 'whenever', require: false
require: false
➡︎ アプリケーションには反映させずに、ターミナルにのみ反映させるターミナル$ bundle2.
「schedule.rb」
を作成ターミナル$ bundle exec wheneverize .3.
「schedule.rb」
を編集config/schedule.rbenv :PATH, ENV['PATH'] #絶対パスから相対パス指定 set :output, 'log/cron.log' #ログの出力先ファイルを設定 set :environment, :development #環境を設定 every 1.day do #1日毎に実行 #「DailyMailer」の、「send_when_everyday」メソッドを実行 runner "DailyMailer.self.send_when_everyday" end4.
「cron」
を反映ターミナル$ bundle exec whenever --update-crontabバッチ処理でよく使うコマンド
$ bundle exec whenever
➡︎ cronの設定を確認
$ bundle exec whenever --update-crontab
➡︎ cronを反映
$ bundle exec whenever --clear-crontab
➡︎ cronを削除参考サイト
- 投稿日:2020-04-26T09:35:06+09:00
Rubyの『テスト自動化』(Minitest)について、簡単にまとめてみた。
はじめに
これは、プロを目指す人のためのRuby入門(チェリー本)を読んで理解を自分なりにまとめて書き記した物です。
個人的にわからない箇所を書き記したものとなっていますので、全て書いているわけではありません。
しかし、みんながつまずく箇所は似通っているのでは?と思うのでその点に関しては、要点を絞った内容が書けているのではと思います(たぶん)。今回書くのは、その中でも『第3章:テストを自動化する』(Minitestの基本)についてです。
それでは、内容の方へ入りましょう!
テストを自動化する
ここで学ぶ事は、
・Minitestの基本
です。そして、テスト自動化とは名前の通り『勝手にテストを行ってくれて、ミスがないか確認してくれるものの事』です。
ミスがないかの確認を毎回毎回行うことは効率が悪いためです。●Minitestの基本
まずは、テスト用のフレームワークを用意します。
Rubyにおいてはそのフレームワークの一つとしてMinitestがあります。Minitestを使うメリットは、
・Rubyと一緒にインストールされるため、セットアップが不要
・学習コストの低さ
・Railsのデフォルトのテスティングフレームワークのため、Railsを開発するときにも知識を生かしやすい。今回のテストを行うにおいての簡単な手順としては、
1. Rubyプログラム(テストコード)を書く
2. テストコードの実行
3. テスティングフレームワークが結果をチェックして、結果報告では、実際にテストコードを書いていってみましょう。
test_ruby.rbrequire 'minitest/autorun' # Minitestのライブラリの読み込み class RubyTest < Minitest::Test def test_ruby #メソッド名はtest_で始めるのが必須 assert_equal 'RUBY', 'ruby'.upcase #この部分が検証される部分。 #assert_equalはMinitestのメソッド。意味は後で説明 end endassert_equal 期待する結果, テスト対象となる値や式この本で紹介されているのは、以下の3つのメソッド
(他にもメソッドは存在します。知りたい方は、MinitestのAPI公式ドキュメントへ)#①aとbが等しければテストはパス assert_equal b, a #②aが真であればパス assert a #③aが偽であればパス assert aそして、先ほどの
test_ruby.rb
のテストを実行した結果が$ ruby ruby_test.rb Run options: --seed 35176 # Running: . #←テストの進歩状況を表しています。(今回はテストメソッドが1個だけのためドットが一つだけ) Finished in 0.000979s, 1021.4507 runs/s, 1021.4507 assertions/s. # テストの実行スピード 1 runs, 1 assertions, 0 failures, 0 errors, 0 skipsfailuresとerrorsがどちらも0ならテストをパスしたことになります。
今回はテストにパスした例になりますが、次は失敗例をみてみましょう。●テストの実行結果、失敗例
test_ruby.rbrequire 'minitest/autorun' class RubyTest < Minitest::Test def test_ruby assert_equal 'Ruby', 'ruby'.upcase # assert_equal 'Ruby'に変更 end end$ ruby ruby_test.rb Run options: --seed 18225 # Running: F Failure: RubyTest#test_ruby [ruby_test.rb:5]: ←ruby_test.rb:5からruby_test.rbの5行目でテストが失敗していることが確認できる。 Expected: "Ruby" ←期待された結果 Actual: "RUBY" ←実際の結果 rails test ruby_test.rb:4 Finished in 0.001320s, 757.5753 runs/s, 757.5753 assertions/s. 1 runs, 1 assertions, 1 failures, 0 errors, 0 skips実行結果の説明をします。
今度はドットではなく、『F』に変わりましたが、これはFailureのFです。
その後は、どこで失敗したかが記載されています。●実行結果がエラーの場合
$ ruby ruby_test.rb Run options: --seed 35712 # Running: E Finished in 0.001649s, 606.4282 runs/s, 0.0000 assertions/s. 1) Error: RubyTest#test_ruby: NoMethodError: undefined method `upcase' for nil:NilClass Did you mean? case ruby_test.rb:5:in `test_ruby' 1 runs, 0 assertions, 0 failures, 1 errors, 0 skips今度は、『F』だったところが、Errorの『E』へと変わりました。
1) Error:以降はエラー内容の詳細になります。
1 runs, 0 assertions, 0 failures, 1 errors, 0 skips
から、1件のエラーで終わったことが確認できました。
- 投稿日:2020-04-26T07:55:48+09:00
windows10(WSL2)でRailsの環境構築をしてみた~Rails導入/起動まで~(2)
はじめに
前回記事にてWSL2の導入ができましたが、今回はWSL2を用いて実際にUbuntu 18.04に環境を構築していきます。
Ruby(Rails)導入
@ksh-fthr さんの以下記事を参考にしました。
Windows10 で WSL を使って Rails 環境を構築したときのメモ
見出しRails 環境を構築しよう
の1~8
を実施してください。今回しようとしているのは上記の記事と若干違うので、以下の点だけ異なっています。
・Ruby 2.6.6
を導入
・sqlite3ではなくmysqlを導入するので7.sqliteを入れよう
は実施不要WebPackerの導入
rails6
からWebpacker
が必須となり、Webpackerを入れないと、Railsアプリ作成の際にエラーが出てしまいます。
Ubuntu 18.04 LST
にて以下コマンドを実行してください。まず、
Webpacekr
をインストールするためのyarn
をインストールします。
単純にapt-get install yarn
だけだとバージョンが古くてWebpackerをインストールできなかったので、以下コマンドでバージョンの新しいyarnを入れます。Ubuntu18.04curl -sS https://dl.yarnpkg.com/debian/pubkey.gpg | sudo apt-key add - sudo apt-get update sudo apt-get install yarn本命のWebpackerを導入します。
Ubuntu18.04rails webpacker:installmysqlの導入
今回はsqliteの代わりに
mysql
を導入します。
Ubuntu 18.04 LST
にて以下コマンドを実行してください。mysqlの導入
Ubuntu18.04sudo apt-get install mysql-server mysql-clientmysqlのバージョン確認
Ubuntu18.04実行コマンド mysql --version 実行結果 mysql Ver 14.14 Distrib 5.7.29, for Linux (x86_64) using EditLine wrapperバージョンが表示されれば導入完了です。
mysql
にはデフォルトでroot
ユーザが用意されていますが、これをrails上で使用するとすると、権限の問題で弾かれてしまいます。
root以外のユーザを作成し、きちんと権限も与えてあげましょう。
以下、コマンド例になります。ユーザ作成例(rootで実行)
CREATE USER railsuser@'localuser' IDENTIFIED BY '******(パスワード)'権限付与例(rootで実行)
GRANT ALL ON *.* TO railsuser@'localuser';Atom導入
今回はエディターとして
Atom
を利用します。
Ubuntu 18.04 LST
にて以下コマンドを実行してください。Ubuntu18.04sudo apt-get install mysql-server mysql-client以下コマンドを実行すると、Atom がGUIで立ち上がってきます。
Ubuntu18.04atomRails サーバ起動
Ubuntu 18.04 LST
上でRailsサーバを起動していきます。1. アプリ作成
新しいアプリ作成します。
Ubuntu18.04rails new sample -d mysql cd sample2. mysql設定ファイル編集
/config/database.yml
にmysqlのログイン情報を記載します。database.yml# MySQL. Versions 5.5.8 and up are supported. # # Install the MySQL driver # gem install mysql2 # # Ensure the MySQL gem is defined in your Gemfile # gem 'mysql2' # # And be sure to use new-style password hashing: # https://dev.mysql.com/doc/refman/5.7/en/password-hashing.html # default: &default adapter: mysql2 encoding: utf8mb4 pool: <%= ENV.fetch("RAILS_MAX_THREADS") { 5 } %> username: railsuser password: ******(パスワード) socket: /var/run/mysqld/mysqld.sock
username
とpassword
をmysql導入時に設定した内容にしてください。また、テスト・開発・本番用のDBはあらかじめmysqlにて作成しておいてください。
3. サーバ起動
サーバを起動します。
Ubuntu18.04rails s
- 投稿日:2020-04-26T05:20:55+09:00
WSL2でRailsの環境構築をしてみた~WSL2導入まで~(1)
はじめに
web開発に関してはmacユーザが多いと思うが、windowsでも WSL( Windows Subsystem for Linux) なるものでLinuxでのRailsの開発環境をある程度整えることができたので、備忘として残そうと思います。
環境 Windows 10 Home 64bit WSLを導入する
WSLの導入には@yoshigeさんの以下記事が非常に参考になりました。
まずは、以下の記事を参考にWSL1を導入し、初期設定まで済ませます。
Microsoft StoreでLinuxのディストリビューションを選んで導入することになるが、自分はUbuntu 18.04 LTS を導入しました。
初心者のためのWSL( 1 ) ~初期設定,CUI設定編~GUIも使えた方が便利なので、以下記事を参考にGUI設定まで済ませます。
初心者のためのWSL( 2 ) ~GUI設定,デスクトップ環境設定編~WSL2を導入する
WSL2の導入は少し複雑です。
1. Windows10 Insider Preview に登録 ⇒ ビルド更新
WSL2はビルドが
18917
以上でないと導入できません。以下URLの手順に沿ってWindows10 Insider Preview に登録しビルドを更新してください。
https://insider.windows.com/ja-jp/getting-started/#register2. ビルドを確認する
設定
⇒システム
⇒バージョン情報
でOSビルド欄をみて、18917
以上であることを確認してください。3. 仮想マシン有効化
以下コマンドを管理者権限のPowerShellで実行し、再起動してください。
powershell
Enable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform
4. WSL2へ切り替え
以下、コマンドを管理者権限のPowerShellで実行してください。
ビルドが18917
以上でないと、以下コマンドは実行できません。現在のWSLバージョンを確認する
実行コマンド wsl -l -v 出力結果 NAME STATE VERSION * Ubuntu-18.04 Running 1WSLバージョンを2へ切り替える(結構時間がかかるかもしれません)
wsl --set-version Ubuntu 2切り替え後のバージョンを確認する
実行コマンド wsl -l -v 出力結果 NAME STATE VERSION * Ubuntu-18.04 Running 2WSLのバージョンが「2」になっていることを確認出来たらWSL2の導入は完了です。
- 投稿日:2020-04-26T05:20:55+09:00
windows10(WSL2)でRailsの環境構築をしてみた~WSL2導入まで~(1)
はじめに
web開発に関してはmacユーザが多いと思いますが、windowsでも WSL( Windows Subsystem for Linux) なるものでLinuxでのRails開発環境をある程度整えることができました。
備忘として残そうと思います。
環境 Windows 10 Home 64bit また、今回導入したものは以下となります。
導入したもの Ruby 2.6.6 Rails 6.0.2.2 mysql for linux 14.14 Atom 1.45.0 WSLを導入する
WSLの導入には@yoshigeさんの以下記事が非常に参考になりました。
まずは、以下の記事を参考にWSL1を導入し、初期設定まで済ませます。
Microsoft StoreでLinuxのディストリビューションを選んで導入することになるが、自分はUbuntu 18.04 LTS を導入しました。
初心者のためのWSL( 1 ) ~初期設定,CUI設定編~GUIも使えた方が便利なので、以下記事を参考にGUI設定まで済ませます。
初心者のためのWSL( 2 ) ~GUI設定,デスクトップ環境設定編~WSL2を導入する
WSL2の導入は少し複雑です。
1. Windows10 Insider Preview に登録 ⇒ ビルド更新
WSL2はビルドが
18917
以上でないと導入できません。以下URLの手順に沿ってWindows10 Insider Preview に登録しビルドを更新してください。
https://insider.windows.com/ja-jp/getting-started/#register2. ビルドを確認する
設定
⇒システム
⇒バージョン情報
でOSビルド欄をみて、18917
以上であることを確認してください。3. 仮想マシン有効化
以下コマンドを管理者権限のPowerShellで実行し、再起動してください。
Enable-WindowsOptionalFeature -Online -FeatureName VirtualMachinePlatform4. WSL2へ切り替え
以下、コマンドを管理者権限のPowerShellで実行してください。
ビルドが18917
以上でないと、以下コマンドは実行できません。現在のWSLバージョンを確認する
実行コマンド wsl -l -v 出力結果 NAME STATE VERSION * Ubuntu-18.04 Running 1WSLバージョンを2へ切り替える(結構時間がかかるかもしれません)
wsl --set-version Ubuntu 2切り替え後のバージョンを確認する
実行コマンド wsl -l -v 出力結果 NAME STATE VERSION * Ubuntu-18.04 Running 2WSLのバージョンが「2」になっていることを確認出来たらWSL2の導入は完了です。
WSL2へ切り替えた後の設定
1. .bash_profileを編集
WSL2に切り替えた後だと、ターミナル立ち上げの際に
.bashrc
を読み込んでくれない仕様になっているようです。参考
WindowsTerminalやPowerShellからWSL2を実行した際に~/.bashrcが読み込まれない自分は
.bash_profile
に以下を追加することで回避しました。if [[ -f ~/.bashrc ]] ; then ~/.bashrc fi3. GUI設定の変更
WSL2はWSLと違い、仮想マシン上でLinuxを動作させています。
参考
https://www.atmarkit.co.jp/ait/articles/1906/14/news019.htmlなのでWSLと違い、window環境 ⇔ Linux環境のIPアドレスが別々に扱われます。
以下、windowsのコマンドラインでipconfigを実行した例になります。
Wireless LAN adapter Wi-Fi: IPv4 アドレス . . . . . . . . . . . .: xxx.xxx.xxx.xxx サブネット マスク . . . . . . . . . .: 255.255.255.0 デフォルト ゲートウェイ . . . . . . .: xxx.xxx.xxx.1 イーサネット アダプター vEthernet (WSL): IPv4 アドレス . . . . . . . . . . . .: yyy.yyy.yyy.yyy サブネット マスク . . . . . . . . . .: 255.255.240.0 デフォルト ゲートウェイ . . . . . . .: yyy.yyy.yyy.1新しく
イーサネット アダプター vEthernet (WSL)
が追加されていることがわかります。
IPが起動するたびに変更されるので、Xlaunchの待受け先もそれに伴い修正する必要があります。GUI設定にて.bashrcに
export DISPLAY=localhost:0
と記載していた部分を以下のように修正します。export DISPLAY=$(cat /etc/resolv.conf | grep nameserver | awk '{print $2}'):0これで、IPアドレスが変更されても、設定しなおすことなくGUIが立ち上がります。
- 投稿日:2020-04-26T04:39:13+09:00
HerokuでのデプロイでPrecompiling assets failed.が出たときの対処法
初めてHerokuでデプロイを行なったらPrecompiling assets failed.というエラーが出てきてしまったので備忘録として投稿します。こちらのエラー、原因は色々あるみたいですので、下記の解決法が全てではありません。
開発環境
MacOS 10.15.4
Ruby 2.5.1
Rails 5.2.3最初に
エラーは目立つ部分が全てではない!!
remote: ! Precompiling assets failed.こちらの一文は赤字で目立ちますが、実は大事な部分がターミナルをさかのぼると出てきます。
エラー1
さかのぼるとこの様なエラーが出てきました。
NoMethodError: undefined method `[]' for nil:NilClass[]を見て思い出しました!!
環境変数セットしてなかった...
私はcredentials.yml.encを使っていたので、下記のコードで環境変数を設定致しました。$ heroku config:set RAILS_MASTER_KEY=`cat config/master.key`デプロイします。
$ git push heroku masterエラー2
上記で環境変数をセットしたにもかかわらず、またしてもPrecompiling assets failed.が出現しました。
ターミナルをさかのぼります。
エラー文が変わっている!!先ほどのエラーは解決できた様です。続いてはこちら
Uglifier::Error: Unexpected token: name (任意の内容). To use ES6 syntax, harmony mode must be enabled with Uglifier.new(:harmony => true).「ES6を使うにはUglifier.new(:harmony => true)でharmony modeを有効してください」ということらしいです。エラー文で検索するとすぐに対処法が出てきました。
config/environments/production.rbを編集します。config/environments/production.rb
config.assets.js_compressor = :uglifier #削除 config.assets.js_compressor = Uglifier.new(harmony: true) #追加gitに変更を上げて、再度
$ git push heroku master無事デプロイできました!!
最後に
冒頭にも書きましたが、こちらのエラーはターミナルをさかのぼるとエラー内容が分かりますので、まずはそちらのエラー内容でググってみてください!
参考
https://teratail.com/questions/163759
https://qiita.com/terufumi1122/items/27bf288414569e13e050
- 投稿日:2020-04-26T01:45:13+09:00
Rails テーブルの制約について
Rails初心者の備忘録です。制約とは
Railsでテーブルのカラムやデータに制限を加え、想定通りの値が入るようにします。
例えば郵便番号のように数値のデータが欲しいとき、文字列が入ってしまうと機能がおかしくなってしまうこともあります。
そのため、制約を設定します。制約の種類
データ型
一般的によく使われているのがデータ型で、以下のようなものがあります。
string 短い文字
text 長い文字
integer 数値(整数)
float 数値(浮動小数)
date 日付
datetime 日時
time 時刻
boolean 真偽NOT NULL制約
空欄を禁止する制約です。
null: false
を付けます。class CreatePostImages < ActiveRecord::Migration[5.1] def change create_table :post_images do |t| t.text :shop_name t.text :image_id, null: false #これ t.text :caption t.integer :user_id t.timestamps end end endUNIQUE制約
重複を禁止する制約です。
unique: true
を付けます。
例えば、同じユーザーネームを登録できないようにしたい時などに使えると思います。class CreatePostImages < ActiveRecord::Migration[5.1] def change create_table :post_images do |t| t.text :shop_name, unique: true #これ t.text :image_id, null: false t.text :caption t.integer :user_id t.timestamps end end endDEFAULT制約
初期値を設定しておく制約です。
:default => ''
を付けます。class CreatePostImages < ActiveRecord::Migration[5.1] def change create_table :post_images do |t| t.text :shop_name, null: false t.text :image_id, unique: true t.text :caption, :null => false, :default => 'これは例です。' #これ t.integer :user_id t.timestamps end end end主キー制約
主キーが必ずあって、重複もしてはいけないという制約です。idなどでよく使われるみたいです。
Railsでは、テーブルを作成する際にidカラムに元々実装されています。外部キー制約
IDなどのキーを利用してテーブルとテーブルを関連付けているとき、親元のテーブルにデータが存在していなければいけないという制約です。
やり方はいろいろあるみたいですが、reference型のものを記載します。
t.reference :user
の後にforeign_key: true
を付けます。このとき、カラム名は`
user_id
で、自動でインデックスを割り振ってくれます。嬉しい。笑class CreatePostImages < ActiveRecord::Migration[5.1] def change create_table :post_images do |t| t.text :shop_name, null: false t.text :image_id, unique: true t.text :caption, :null => false, :default => 'これは例です。' t.references :user, foreign_key: true #これ t.timestamps end end end
他にもいろいろとあるみたいですが、重要なものをメモしてみました。参考にしたサイト
- 投稿日:2020-04-26T01:05:37+09:00
【Rails】日本語表記化(ページネーション、エラーメッセージ)
railsで英語表記になっているものを日本語にする方法があります。
ページネーション
Railsのgemである
will_paginate
のラベルを日本語に変えます。実装
まず
config/environment.rb
に以下を記述します。config/environment.rbWillPaginate::ViewHelpers.pagination_options[:previous_label] = '< 前へ' WillPaginate::ViewHelpers.pagination_options[:next_label] = '次へ >'そして該当のページネーションに追記します。
<%= will_paginate %> ↓ <%= will_paginate , previous_label: '< 前へ', next_label: '次へ >'%>これで実装できます。
エラーメッセージ
実装
Gemfileにて下記をインストール
Gemfilegem 'rails-i18n'次に
config/application.rb
で以下を追記config/application.rbconfig.i18n.default_locale = :jaこれだけでも日本語表記化されますがモデルのカラム名などが英語のままです。
そこでconfig/locales
内にja.yml
を追加し下記を入力してください。config/locales/ja.ymlja: activerecord: models: user: ユーザー attributes: user: name: 名前 email: メールアドレスこれで名前とメールアドレスが英語表記になります。
- 投稿日:2020-04-26T00:23:17+09:00
Railsの開発環境でサブドメインをテストする
概要
Railsではデフォルトではlocalhost:3000で開発環境にアクセスできますが、
ルーティングをサブドメインで切り替えるテストをしたいなと思った時にハマったので、解決策を示します。ルーティング
routes.rb# hostがexample.comの時だけアクセスさせたい constraints host: example.com do get 'top', to: 'top#index' end新しいドメインを追加する
OSがmacまたはlinuxの場合は、/etcディレクトリに、windowsの場合はC:\Windows\System32\driversに存在するhostsファイルに新しいドメインを追加します。
hosts127.0.0.1 localhost example.comこれで、127.0.0.1というIPアドレスにlocalhostとexample.comというホスト名を設定できました。
Blacked Hostsの設定
Rails6を使用している場合は、アクセス可能なホストにexample.comを追加しましょう。
Blacked HostsはRails6の新機能で、ブラウザがRailsアプリケーションにアクセスする際に使用できるホスト名を制限するためのものです。
デフォルトでlocalhostのみが許可されています。config/initializers/blocked_hosts.rbRails.application.configure do config.hosts << "example.com" endこれで、以下サブドメインにアクセスすることができます。
http://example.com:3000/top