- 投稿日:2020-03-16T23:41:37+09:00
【MySQL】プログラミング初心者が今まで遭遇したエラーとその解決方法のメモ
こんばんは!スージーです!
なかなか技術ブログが書けずにモヤモヤしていたので、ちょうど良いネタがあり備忘録も兼ねて。MySQLに接続できないエラー
私は度々、MySQLに接続できずに四苦八苦しています。pidファイルないよーとかsocketないよーとか、その度に過去のメモや参考記事をあちこち探しているのでまとめてみようと思います。
参考
- 【MySQL】pid not foundもしくはpermission deniedの対応方法 https://qiita.com/AK4747471/items/36b73edd9d1e666ae0c0
- RailsプロジェクトでMySQLがbundle installできなかった https://qiita.com/akito19/items/e1dc54f907987e688cc0
- Library not loaded: /usr/local/opt/mysql/lib/libmysqlclient.21.dylib (LoadError) https://note.com/shoki_rails/n/nf7b51ba48084
- mysqlのsocketエラーでrailsアプリが起動できない https://qiita.com/fujitora/items/d341c52706d1954cae28
- mysqld_safe A mysqld process already existsが出た時の対処方法 https://www.takafumitaba.com/mysql-already-exists
- MySQLが再起動しなくなったときに行う3つの手順 https://engineer.evisu0414.com/mysql001/
【遭遇率第1位】
Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)
原因:
ざっくり言うとmysql.sockファイルが存在しないから作ってね
解決策:
/tmp直下にmysql.sockを作るmysql.sockファイルがあるか確認 ~ $cd /tmp tmp $ ls mysql.sockがない tmp $ sudo touch mysql.sock tmp $ cd ~ $ sudo mysql.server start ERROR!~~~ startできずエラー発生したら 権限の書き換え(chownでファイルやディレクトリの所有者と所属グループを変更する) ~ $ sudo chown username /tmp/mysql.sock もしくは権限付与 ~ $ sudo chmod 777 /tmp/mysql.sock もう一度mysql起動 ~ $ sudo mysql.server start ...SUCCESS!mysql.sockファイルの作り方は色々あると思いますが、私はこのエラーが起きた時は
touch
コマンドで/tmp/
ファイル直下にmysql.sock
ファイルを直接作ってしまいます。socketファイル作成しても権限がないと怒られる事もあるのでその時はchown
コマンドかchmod
コマンドで権限の書き換えか権限付与してあげて下さい。【遭遇率第2位】
Can't connect to local MySQL server through socket '/tmp/mysql.sock' (38)
原因:
ざっくり言うとpidファイルが存在しないから作ってね
解決策:
/usr/local/var/mysql/直下にlocal.pidファイルを作る~ $ sudo mysql.server start Starting MySQL … ERROR! server quit updating PID file(/usr/local/var/mysql/usernoMacBook-ea.local.pid) pidファイルがあるか確認してみる ~ $ cd /usr/local/var/mysql mysql $ ls usernoMacBook-ea.local.pidがない mysql $ sudo touch usernoMacBook-ea.local.pid mysql $ cd ~ $ sudo mysql.server start ...ERROR!~~/usr/local/var/mysql/username.local.err: Permission denied 権限ないよと怒られたら先ほどのエラーと同様に権限の書き換え(chownでファイルやディレクトリの所有者と所属グループを変更する) ~ $ sudo chown /usr/local/var/mysql/usernoMacBook-ea.local.pid もしくは権限付与 ~ $ sudo chmod 777 /usr/local/var/mysql/usernoMacBook-ea.local.pid もう一度起動してみる ~ $ sudo mysql.server start ...SUCCESS!先ほどと同様にやり方は色々あると思いますが、
pid
ファイルもtouch
コマンドで作ってあげましょう。mysql.sock
のエラーと同様に権限ないよって怒られたら権限の書き換えか権限付与してあげましょう。ここまでのまとめ
ここまで紹介した
mysql.sock
ないよ、~.local.pid
ないよ、権限
ないよ、がMySQL関連エラーの大半を占めていると思います。「/tmpディレクトリってどこ!?」とか「/usrディレクトリなんて知らないよ」って最初は思いましたが、まずはファイルが無い事を確認する為にcd
コマンドで該当ディレクトリまで潜って見てみましょう。【遭遇率第3位】
mysql立ち上がった!と思ったらsafeモードのプロセスが既に存在してますよっていうエラー
原因:
既にMySQLのプロセスが動いている
解決法:
processをkillする~ $ sudo mysql.server start Starting MySQL SUCCESS! ~ $ 200315 13:51:58 mysqld_safe A mysqld process already exists 動いているMySQLプロセスを確認してみる ~ $ ps aux| grep mysqld user 98762 0.0 0.0 4268296 672 s004 S+ 2:00PM 0:00.01 grep mysqld user 98633 0.0 5.4 4929884 450652 ?? S 1:51PM 0:00.46 /usr/local/opt/mysql@5.6/bin/mysqld --basedir=/usr/local/opt/mysql@5.6 --datadir=/usr/local/var/mysql --plugin-dir=/usr/local/opt/mysql@5.6/lib/plugin --log-error=usernoMacBook-ea.local.err --pid-file= usernoMacBook-ea.local.pid user 98536 0.0 0.0 4281052 1128 ?? S 1:51PM 0:00.03 /bin/sh /usr/local/opt/mysql@5.6/bin/mysqld_safe --datadir=/usr/local/var/mysql ←注目 mysqld_safeプロセスが動いている模様 プロセスをkillする ~ $ sudo kill -9 98536 Password: 一度mysqlを停止する ~ $ mysql.server stop Shutting down MySQL .. SUCCESS! もう一度MySQLを起動してみる ~ $ mysql.server start Starting MySQL . SUCCESS!これはこの前初めて遭遇したエラーです。頻出エラーより遭遇確率は低いと感じますが、
grep
してmysql_safe
のプロセスが動いているか確認しましょう。mysql_safe
以外のプロセスをkillしてもエラー解消しなかったので悪さしているmysql_safeを見つけてあげましょう。【番外編】
過去に一度でも5.7を起動してしまうと、同じデータを使って5.6を起動すると今までの方法では解決できない場合がある。
この状況は過去に一度dockerでMySQL@5.7で起動した後に開発環境のMySQL@5.6を起動した時に起きた事があります。
この状況になったらMySQLをアンインストールする方法があります。ただし、開発環境で大切なデータがDBに残っている場合は何らかの方法で退避させてあげて下さい(退避方法は割愛します。実践した事ないです)。私は幸いにも開発環境に貴重なデータはないので躊躇無くアンインストールしました。
mysqlをアンインストールします ~ $ brew remove mysql ~ $ brew cleanup 以下のディレクトリ下にはmysql関連ファイルが作成されているので念の為、綺麗に削除しておきます ~ $ sudo rm -rf /usr/local/mysql ~ $ sudo rm -rf /Library/StartupItems/MYSQL ~ $ sudo rm -rf /Library/PreferencePanes/MySQL.prefPane ~ $ sudo rm -rf /Library/Receipts/mysql-.pkg ~ $ sudo rm -rf /usr/local/Cellar/mysql* ~ $ sudo rm -rf /usr/local/bin/mysql* ~ $ sudo rm -rf /usr/local/var/mysql* ~ $ sudo rm -rf /usr/local/etc/my.cnf ~ $ sudo rm -rf /usr/local/share/mysql* ~ $ sudo rm -rf /usr/local/opt/mysql* 最後にver5.6をインストール ~ $ brew install mysql@5.6 インストールが完了したらパス通す $ echo 'export PATH="/usr/local/opt/mysql@5.6/bin:$PATH"' >> ~/.bash_profile .bash_profileの変更を反映 $ source ~/.bash_profile MySQLを起動 ~ $ sudo mysql.server start . SUCCESS!アンインストールしても過去のmysqlファイルがなぜか残っている場合があるので面倒ですけど
rm
コマンドで該当該当ファイルを削除してあげます。完全にクリーンになったMySQLならちゃんと起動してくれます。【番外編2】
rails new project-name -d mysql→ Library not loaded: /usr/local/opt/mysql/lib/libmysqlclient.21.dylib (LoadError)
原因:
mysqlのライブラリーがロードできませんよ
対策:
mysql2をアンインストールしてbundle installproject-name $ bundle exec gem uninstall mysql2 project-name $ bundle install . .. ... Gem::Ext::BuildError: ERROR: Failed to build gem native extension. current directory: /Users/akito/git/media/vendor/bundle/gems/mysql2-0.4.4/ext/mysql2 /Users/akito/.rbenv/versions/2.3.1/bin/ruby -r ./siteconf20160929-55293-192vx35.rb extconf.rb checking for ruby/thread.h... yes checking for rb_thread_call_without_gvl() in ruby/thread.h... yes checking for rb_thread_blocking_region()... no checking for rb_wait_for_single_fd()... yes checking for rb_hash_dup()... yes checking for rb_intern3()... yes ----- Using mysql_config at /usr/local/bin/mysql_config ----- checking for mysql.h... yes checking for errmsg.h... yes checking for mysqld_error.h... yes ----- 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/5.7.14/lib ----- creating Makefile To see why this extension failed to compile, please check the mkmf.log which can be found here: /Users/akito/git/media/vendor/bundle/extensions/x86_64-darwin-15/2.3.0-static/mysql2-0.4.4/mkmf.log current directory: /Users/akito/git/media/vendor/bundle/gems/mysql2-0.4.4/ext/mysql2 make "DESTDIR=" clean current directory: /Users/akito/git/media/vendor/bundle/gems/mysql2-0.4.4/ext/mysql2 make "DESTDIR=" compiling client.c compiling infile.c compiling mysql2_ext.c compiling result.c compiling statement.c linking shared-object mysql2/mysql2.bundle 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/akito/git/media/vendor/bundle/gems/mysql2-0.4.4 for inspection. Results logged to /Users/akito/git/media/vendor/bundle/extensions/x86_64-darwin-15/2.3.0-static/mysql2-0.4.4/gem_make.out An error occurred while installing mysql2 (0.4.4), and Bundler cannot continue. Make sure that `gem install mysql2 -v '0.4.4'` succeeds before bundling. 盛大に怒られている...以下の参考記事の通りにやってみます
RailsプロジェクトでMySQLがbundle installできなかった
https://qiita.com/akito19/items/e1dc54f907987e688cc0project-name $ bundle config --local build.mysql2 "--with-ldflags=-L/usr/local/opt/openssl/lib --with-cppflags=-I/usr/local/opt/openssl/include" project-name $ bundle install . .. ... Bundle complete! 18 Gemfile dependencies, 78 gems now installed. Use `bundle info [gemname]` to see where a bundled gem is installed. run bundle exec spring binstub --all * bin/rake: Spring inserted * bin/rails: Spring inserted 正常にbundle install完了したみたい project-name $ rails db:create Created database ‘project-name_development’ Created database ‘ project-name_test’ project-name $ rails db:migrate project-name $ rails s => Booting Puma => Rails 5.2.4.1 application starting in development => Run `rails server -h` for more startup options Puma starting in single mode... * Version 3.12.4 (ruby 2.5.1-p57), codename: Llamas in Pajamas * Min threads: 5, max threads: 5 * Environment: development * Listening on tcp://localhost:3000 Use Ctrl-C to stop きたきたきたーーーー!!!!localhost:3000にアクセスすればいつものrails初期画面が表示されます。MySQLエラーのドツボにハマってrails sでサーバ起動できた時は快感ですね。
【忘れがちなコマンド覚書き】
sudo mysql.server start
→MySQLを立ち上げます
sudo mysql.server stop
→MySQLを停止します
sudo mysql.server restart
→MySQLをstop&startします
sudo mysql.server status
→MySQLの状態を確認します
ps aux| grep mysqld
→MySQLのプロセスを探します
まとめ
以上、私が遭遇したMySQLエラーのまとめでした。自分で何度も遭遇して解決しているうちに遭遇するパターンが同じだったので一覧で見れるようにしておけば後から振り返る時に便利だなと思い久々にQiitaを書いてみました。今回は初めてipadでこの記事を全部書いてみましたが、以外と快適に書けたのでipadとsmart keybord買った甲斐がありました。
終わり
- 投稿日:2020-03-16T23:25:49+09:00
railsタグ検索機能(railsチュートリアル後の機能追加)
はじめに
今回は前回追加した、タグ付機能を利用してタグ検索機能を追加します。
前回の記事(タグ付機能)
https://qiita.com/E6YOteYPzmFGfOD/items/bfffe8c3b31555acd51d作るもの
マイクロポストタグ付機能を利用したタグ検索機能。(題材は自分のポートフォリオです。)
対象読者
railsチュートリアルに機能を追加したい等自分と同じ位のレベルの人を対象としています。
作成の流れ
1.検索フォームの作成
2.コントローラーのアクション作成
3.動作確認1.検索フォームの作成
今回は検索フォームをroot_path上に設けます。(自分のポートフォリオがマイクロポストの一覧をroot_path(static_pages/home)に設けているため)
app/views/static_pages/home<%= form_with url: root_path, method: :get, class: '自由に' do %> <%= select_tag :tag_id, options_from_collection_for_select(Tag.all, :id, :name, params[:tag_id]), { prompt: 'タグで絞り込み', class: ,'自由に' onchange: 'submit(this.form);' }%> <% end %>fomr_withを使って検索フォームを作ります。各指定している値を自分なりに説明します。
url: 検索した後に移動するページ。(getメソッド後の移動するページ)
method::get 検索時はゲットメソッドを使用する。(root_urlにゲットアクションを起こすのでstatic_page_contorollerのhomeアクションに飛びます。
)
select_tag: フォームの中でセレクトタグを表示するためのメゾット
select_tag:オブジェクト名(tag_id)URLのクエリ(検索するとURLの?以降に表示されてます)
options_from_collection_for_select(
第1引数:オブジェクトのリスト(Tag.all全件表示)
第2,3引数:取得したリストの表示。順番が大切でid,nameの順にすることによりタグnameを表示する。(idを基準に表示する。逆の順番にするとidの数字だけが表示される。)
第4引数:検索後に表示する値。params[:tag_id]とすることによりURLのクエリからidを取得して検索後もフォームにタグ名を表示します。(第2、第3の引数の値が重要です。)
)
{promt:は何も選択していないときに表示される値です。
onchange:submit(this.form)はJavaScriptを実行できるものでセレクトボックスが選択されたときにこの検索がスタートするようにしています。
}続いてコントローラーです。
app/controllers/static_pages_controller.rb@microposts = params[:tag_id].present? ? Tag.find(params[:tag_id]).microposts : Micropost.all ※ページネーション等に渡してくださいタグ検索が実行されるとparamsでURLのクエリ(tag_id)を取得してfindでテーブルの中を探し関連付けしているのでmicropostsで関連するマイクロポストを取得します。検索されていない場合は全てのマイクロポストを取得するようにしています。
おまけ
URLのクエリとはURL上に表示されている?以降のやつです。
なんちゃら.com/?utf8=✓&tag_id=1
paramsメゾットではgetメゾット時にURLのクエリを取得できます!
※ログを見るとこんな記述もあります。
Parameters: {"utf8"=>"✓", "tag_id"=>"2"}以上でタグ検索機能は完成となります。最後までお読みいただきありがとうございました。
アドバイス等いただけるととても喜びます。次はマイクロポストの検索機能を記事にしたいと思います。
ありがとうございました。
- 投稿日:2020-03-16T23:14:10+09:00
Rails + jQuery + AjaxでCRUDのサンプルプロジェクト [Hello World]
React + JQuery(+Vanilla JS) + AjaxによるCRUD(作成/読み込み/更新/削除)のサンプルプロジェクトです。 ※Vanilla JSは純粋のJavaScriptです。
動作確認はChrome、FireFox、Microsoft Edge、IE11です。恐らくマックさんのブラウザでも動作するはずです。
DEMO
https://www.petitmonte.com/rails-demo/jquery_crud
ソース一式
https://github.com/TakeshiOkamoto/mpp_jquery_crud
※学習用の為、ライセンスはパブリックドメイン
- 投稿日:2020-03-16T23:05:50+09:00
二次元配列の格納方法
こんちは!
今日はrails上で二次元配列の格納方法を記載します。理由
この内容が容易に見当たらなかったため、他の方の助けになればと思います。
一次元配列の格納方法
イメージとしては、[1,2,3,4,5,6]
という風に格納したい場合、railsではコントローラーに以下のように記載するとできます。tests_contoroller.rbdef idex @test = [] #配列の宣言 6.times do |i = 0| #6回読み込ませる、そしてiには0を格納している。iは初期化式 @test[i] = i + 1 #初期化式で宣言したiに1足した数字を各配列に代入している。 i += 1 #iに1を足してはじめに戻る。何もしないままはじめに戻ると同じ配列[0]を六回繰り返すだけだから end # 配列[i]になぜ1を足さないかは、配列の初期値は[0]だから二次元配列の格納方法
次は二次元配列です。
イメージとしては[[1,1],[2,1],[3,1]]
と格納したい場合は以下の通りになります。tests_contoroller.rbdef idex @test = [] #配列の宣言 3.times do |i = 0| #3回読み込ませる、そしてiには0を格納している。iは初期化式 @test[i] = [i + 1,1] i += 1 end@test[i] ←の部分は、一緒です。
その配列の中に、さらに配列を入れるイメージです。
|1|1|
|2|1|
|3|1|これを使った応用で、以下のようなコードが表示が実現できます。
<select name="exp_year" id="exp_year"><option value="">--</option> <option value="2020">20</option> <option value="2021">21</option> <option value="2022">22</option> <option value="2023">23</option> <option value="2024">24</option> <option value="2025">25</option> <option value="2026">26</option> <option value="2027">27</option> <option value="2028">28</option> <option value="2029">29</option> <option value="2030">30</option></select>HTML上表示したいものは、1つめの配列に格納されています。
valueの値は、2つめに格納したものがです。格納例としては、以下の通り
|20|2020|
|21|2021|
|22|2022|
|23|2023|これらは以下のコードをコントローラー側に入力すると、vew側で表示でます。
tests_controller.rbdef index year = 2020 @year = [] 11.times do |i = 0| @year[i] = [year - 2000,year] year += 1 i += 1 end endvewには以下の一文追加してね。
tests/test.html.haml= select_tag 'exp_year',options_for_select((@year),class: "exp_year"),prompt: "--"追加したら以下のように見れるはずです。(CSSは適当に付けてみるとよいでしょう)
以上です!
またこう言った、見当たらなかったものをあり次第、アップしていきます!ほなねー。
- 投稿日:2020-03-16T22:43:58+09:00
【Rails】flashメソッド
flashメソッド
ユーザーの登録成功や失敗をメッセージ形式で知らせてくれるメソッド。
実行例
controllers/users_controller.rbdef create @user = User.new(user_params) if @user.save flash[:success] = "Welcome to the Sample App!" redirect_to @user else render 'new' end end上記ではユーザーの登録に成功した時に、
flash[:success] = "Welcome to the Sample App!"
が実行され成功メッセージが表示されるようになっています。
しかしビューの方でも設定を行わないと表示されるようにはなりません。app/views/layouts/application.html.erb<省略> <body> <%= render 'layouts/header' %> <div class="container"> <% flash.each do |message_type, message| %> <div class="alert alert-<%= message_type %>"><%= message %></div> <% end %> <%= yield %> <%= render 'layouts/footer' %> <%= debug(params) if Rails.env.development? %> </div> <省略>
<% flash.each do |message_type, message| %>
でflashの数だけメッセージが表示されるようになっております。bootstrapを使用していると
<div class="alert alert-<%= message_type %>">
でメッセージの表示を変更されることができます。
bootstrapには上記の性質があり、今回のコードで登録に成功するとflash[:success]
が実行され<div class="alert alert-<%= message_type %>">
の<%= message_type %>
がsuccess
に変わり緑色のメッセージが表示されます。
- 投稿日:2020-03-16T22:07:44+09:00
【Rails】assert_differenceメソッド
assert_differenceメソッド
処理実行時の値の変化を検証するメソッド。
実行例
assert_difference 'User.count', -1 do delete user_path(@non_admin) end
assert_difference
の第一引数として与えられているUser.count
が、ブロック内で変更されているかを検証しています。
第二引数には第一引数の変更される値を示しています。何も指定しないと+1
になります。assert_no_differenceメソッド
assert_no_difference 'User.count' do delete user_path(@user) endこれも
assert_differenceメソッド
と似たメソッドで、
違いは第一引数であるUser.count
がブロック内の処理によって値が変化していないことを検証しています。
- 投稿日:2020-03-16T20:53:59+09:00
Twitterログイン機能を搭載したRailsアプリを作る
Twitterログイン機能について学習するため、簡素なテストアプリを作成してみることにしたので、その一連の流れを記しておきます。
大きな流れとしては以下のようになります。
- アプリを作成する
- gem「Devise」を導入
- Twitterにアプリを登録し、key情報を取得
- gem「dotenv-rails」を導入して、セキュリティ強化
- Twitterログイン機能の実装
それでは順番に解説していきます!
アプリを作成する
まずはrails newでアプリを作成します。
$ rails new twitter-login-app作成したアプリのディレクトリへ移動します。
$ cd twitter-login-app「Devise」を追加
ログイン機能を使用するため、Deviseというgemを使用します。
Gemfilegem 'devise'$ bundle installDeviseをインストールします。
$ rails g devise:install Running via Spring preloader in process 807 create config/initializers/devise.rb create config/locales/devise.en.ymlDeviseで使用するViewファイルを作成します。
$ rails g devise:views Running via Spring preloader in process 843 invoke Devise::Generators::SharedViewsGenerator create app/views/devise/shared create app/views/devise/shared/_error_messages.html.erb create app/views/devise/shared/_links.html.erb invoke form_for create app/views/devise/confirmations create app/views/devise/confirmations/new.html.erb create app/views/devise/passwords create app/views/devise/passwords/edit.html.erb create app/views/devise/passwords/new.html.erb create app/views/devise/registrations create app/views/devise/registrations/edit.html.erb create app/views/devise/registrations/new.html.erb create app/views/devise/sessions create app/views/devise/sessions/new.html.erb create app/views/devise/unlocks create app/views/devise/unlocks/new.html.erb invoke erb create app/views/devise/mailer create app/views/devise/mailer/confirmation_instructions.html.erb create app/views/devise/mailer/email_changed.html.erb create app/views/devise/mailer/password_change.html.erb create app/views/devise/mailer/reset_password_instructions.html.erb create app/views/devise/mailer/unlock_instructions.html.erbDeviseを使用するモデルを作成します。
$ rails g devise user Running via Spring preloader in process 886 invoke active_record create db/migrate/20200316050323_devise_create_users.rb create app/models/user.rb invoke test_unit create test/models/user_test.rb create test/fixtures/users.yml insert app/models/user.rb route devise_for :users $ rails db:migrateこれでDeviseに対応したuserモデルが作成されました!
Twitterにアプリを登録し、key情報を取得
Twitterログインを実装するため、Twitter Developersへアプリケーション情報を登録します。
未承認の方は申請の手続きからになります。以下の記事が参考になるかと思います。
Twitter API 登録 (アカウント申請方法) から承認されるまでの手順まとめ ※2019年8月時点の情報
登録の際、webサイトURLを指定する箇所を「localhost:3000」などローカル環境のアドレスにするとエラーが表示され登録することができないので、適当なアドレスを入力しておきます。
callback urlには、http://localhost:3000/users/auth/twitter/callback と追加し、「Allow this application to be used to Sign in with Twitter」のチェックボックスにチェックを入れておきます。
アプリケーション作成後、API keyとAPI secret keyの情報を取得しておきます。
「dotenv」を導入して、セキュリティ強化
Twitetrから取得したAPI keyやAPI secret keyの情報をGitなどに公開してしまうと、悪意のある第三者に利用され、損害が発生してしまうリスクがあります。
そのためこうした知られたくない情報は、非公開な情報として扱う必要があります。
そうした時に便利なのが、「dotenv」というgemです。
Gemfilegem 'dotenv-rails'$bundle installその後、Gemfileと同じ位置に「.env」を作成し、先ほどのkey情報を記述します。
.env# Using Twitter API TWITTER_API_KEY=API key TWITTER_SECRET_KEY=API secret key続いて「.gitignore」を編集します。
ここにファイル名を追加することで、特定のファイルをGitの管理対象から除外することができます。.gitignore# See https://help.github.com/articles/ignoring-files for more about ignoring files. # # If you find yourself ignoring temporary files generated by your text editor # or operating system, you probably want to add a global ignore instead: # git config --global core.excludesfile '~/.gitignore_global' # Ignore bundler config. /.bundle # Ignore the default SQLite database. /db/*.sqlite3 /db/*.sqlite3-journal # Ignore all logfiles and tempfiles. /log/* /tmp/* !/log/.keep !/tmp/.keep # Ignore uploaded files in development /storage/* !/storage/.keep /node_modules /yarn-error.log /public/assets .byebug_history # Ignore master key for decrypting credentials and more. /config/master.key .env #ここを追記Twitterログインの実装
Twitterログインは「Oauth」という認証機能を使用します。
まずは必要なgemをインストールします!
Gemfilegem 'omniauth' gem 'omniauth-twitter'gemをインストールします。
$ bundle install先ほど追加したuserモデルにカラムを追加します。
$ rails g migration AddColumnsToUsers uid:string provider:string Running via Spring preloader in process 91573 invoke active_record create db/migrate/20200316073244_add_columns_to_users.rb $ rails db:migrateconfig/initializers/devise.rbを編集します。
config/initializers/devise.rbDevise.setup do |config| #<省略> # ==> OmniAuth # Add a new OmniAuth provider. Check the wiki for more information on setting # up on your models and hooks. # config.omniauth :github, 'APP_ID', 'APP_SECRET', scope: 'user,public_repo' config.omniauth :twitter, ENV['TWITTER_API_KEY'], ENV['TWITTER_SECRET_KEY'] #<省略> enduserモデルに:omniauthableを追加します。
user.rbclass User < ApplicationRecord # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable, :omniauthable end続けて以下のメソッドを追加します。
ログインしたアカウントを確認し、初めてログインする場合は新しくアカウントを作成するメソッドになります。user.rbclass User < ApplicationRecord # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable, :trackable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :validatable, :omniauthable def self.find_for_oauth(auth) user = User.where(uid: auth.uid, provider: auth.provider).first unless user user = User.create( uid: auth.uid, provider: auth.provider, email: User.dummy_email(auth), password: Devise.friendly_token[0, 20] ) user.save! end current_user = user end private def self.dummy_email(auth) "#{auth.uid}-#{auth.provider}@example.com" end endコールバック処理を行うため、app/controllers/users/omniauth_callbacks_controller.rbというコントローラーを作成します。
app/controllers/users/omniauth_callbacks_controller.rbclass Users::OmniauthCallbacksController < Devise::OmniauthCallbacksController def twitter callback_from :twitter end private def callback_from(provider) provider = provider.to_s @user = User.find_for_oauth(request.env['omniauth.auth']) if @user.persisted? flash[:notice] = I18n.t('devise.omniauth_callbacks.success', kind: provider.capitalize) sign_in_and_redirect @user, event: :authentication else session["devise.#{provider}_data"] = request.env['omniauth.auth'] redirect_to new_user_registration_url end end endルーティングを追加します。
config/routes.rbRails.application.routes.draw do devise_for :users, controllers: { omniauth_callbacks: 'users/omniauth_callbacks' } endログインページ作成
Twitterログイン元のページを作成します。
$rails g controller login indexapp/views/login/index.html.erbに、Twitterログインのリンクなどを追加します。
ログイン時はログアウトのリンクを、ログアウト時はログインのリンクを表示できるようにするため、sessionコントローラーを作成します。
$rails g controller session destroysessionコントローラーを以下のように変更します。
ログイン時に保存されるsession情報を削除し、rootにリダイレクトする処理です。sessions_controller.rbclass SessionsController < ApplicationController def destroy reset_session redirect_to root_path end endログイン成功時は「Hello,world!」の文字が表示されるようにします。
views/login/index.html.erb<% if user_signed_in? %> <%= link_to 'Twitter Logout', sessions_destroy_path %> <% else %> <%= link_to 'Twitter Login', user_twitter_omniauth_authorize_path %> <% end %> <% if user_signed_in? %> Hello, world! <% end %>ルーティングを追加します。
config/routes.rbRails.application.routes.draw do root 'login#index' get 'sessions/destroy' devise_for :users, controllers: { omniauth_callbacks: 'users/omniauth_callbacks' } # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html end実際にログインしてみる
まずはサーバーを起動します。
$cd twitter-login-app $rails slocalhost:3000にアクセス・・・
無事ログインでき、リンク表示もログアウトになっています!
- 投稿日:2020-03-16T20:49:34+09:00
ここから始めます。目標をぶち上げる。
はじめに
えー、どうも、圧倒的初心者。NSパンダまんです。
今回はProgateにて基本的な勉強を終了した完全未経験くそごみの私が、今年の8月か9月までに本気でモダンなイケてるナウいポートフォリオを作り、それを引っさげて渋谷のWEB系自社開発企業に内定をもらうことを目標としたサクセスストーリーブログです。
あと、学んだ言語ですが、一応、、、学習教材が多い
短い期間でアプリケーションが作れる。(らしい。実際作ってないから知らん。)
日本人が創り上げた由緒正しき言語である(日本語での問題解決のテキストも多い)
これらの点からファーストチョイスはRubyを選択しました。
Rubyで基礎を深め、そこから他の言語も学んでいこうって寸法です。あと,,,もしこれをみている変わり者なあなた!!
もしあなたが現在プログラミングを学習していて私と同じようなナウい目標を掲げているのなら、、なんかコメントください。
なんでもいいんです。独学でやってるから寂しいんです。寂しがりやなんです。ここでは私とおんなじような目標をたてて頑張っている方と共に目標に向かって頑張って行きたい。そんな願いも込めて書いているのです。
*なお初心者でありインターネットのイの字もわかっておりませんので訳のわからんことを書いていると思ったらばしばしと叩いていただければと思います。コメント欄にベギラゴン唱えても可です。
progateを一通り学び終え、さあ次なにするかとひたすら考えておりました。
progateをやっているうちはどんどんと湧き出てくる新しい知識をひたすらインプットするだけで良かったのでかなり思考停止していたと思います。それが終わったとき、ふと考えてしまったのです。
「あれっこれ次どうすりゃいいの?」ってね。部活の県大会とかで負けた高校生みたいなもんです。完全に方向性を失いました。
それで色々調べたんですけどなんか、、、よくわかんないんですけど
「RAILS チュートリアル」
ってのを発見したのです。最初なんかの本なのかなって思ってAmazonで調べまくりました。でもなんかサイト?電子書籍?みたいな感じみたい。
んで必死の思いで探して。。。(ググったら一発ででました)
見てみたんですけど。。。。。「えっなにこれくっそ読みづらくね??しかも今まで散々インプットしてきたのにまたインプット?お兄さん疲れちゃったよ。もう簡単なアプリ作りたいよ!!」
と正直思いました。やる気になりませんでしたね。あと、なんか外国の方が作っているのかな?それを翻訳した感じでなんか読みづらい。文系のくせに読解能力に疎い私は簡単に2,3分パラパラとページをみて諦めました。笑
とりあえずチュートリアルをすっ飛ばして簡単なアプリ作る方針に決めました。
そこでわからないことあったらまた戻ってインプットすりゃあええと。というわけで次回は環境構築について書いていきたいと思います!!
それでは!!!!
- 投稿日:2020-03-16T19:15:47+09:00
【丁寧解説】Elastic Beanstalkを使ってRailsをサクッとEC2にデプロイしよう
初学者がAWSにデプロイする時、めちゃめちゃ設定あって挫けそうになりませんか?
ええ、わかります。。。
自分も大量のエラーと戦いながら、なんとかデプロイをした経験があります。新しくアプリを作った時にCI/CDを使ってどうデプロイしようか?と
調べていた時にElastic Beanstalkを知りました。実際に使ってみて、とても簡単にデプロイ出来たし、
なによりEC2へデプロイすることの全体像をサクッとつかめるなって思ったので
初学者向けに丁寧に解説しようと思って記事を書きました。デプロイに挫けそうになった方は
ぜひElastic Beanstalktを使って試してみてください!Elastic Beanstalkt とは?
Elastic Beanstalk では、アプリケーションを実行しているインフラストラクチャについて学習することなく、AWS クラウドでアプリケーションをすばやくデプロイし、管理できます。Elastic Beanstalk は、選択肢を狭めたり制御を制限したりすることなく、管理の複雑さを軽減します。アプリケーションをアップロードするだけで、Elastic Beanstalk が自動的に容量のプロビジョニング、負荷分散、拡張、およびアプリケーションの状態のモニタリングといった詳細を処理します。
AWS Elastic Beanstalk とは簡単に言えば、インフラ詳しくなくてもアプリをEC2にデプロイできて、
よくあるアプリのインフラ設計で勝手にチューニングしてくれるよってやつです。料金に関しても使ったAWSリソースのみ(今回の記事ではEC2とRDS、S3)なので、
無料枠内で全然試すことができます。詳しい技術については丁寧に解説してくれている記事が
たくさんあると思うので、興味がある人はそちらをご覧ください。この記事では0からデプロイができるようになることをフォーカスして解説していきます!
はじめに
前提
- AWSアカウントを持っている
- Railsアプリを作成できる
- 簡単なコマンドがわかっている
大まかな流れ
- AWS CLIのインストール・セットアップ
- AWS EB CLIのインストール・セットアップ
- Railsアプリの用意・デプロイの事前準備
- RailsアプリをEC2にデプロイ
この記事のゴール
- EC2にRailsアプリをデプロイできるようになる
- ファイルを更新して、再度デプロイを行い、アプリを継続的に更新できること
AWS CLI のインストール・セットアップ
1. AWS CLI 用の IAM を作成
まずAWS CLI用のIAMを作成し、CLIから操作できるようにします。
AWS: IAMこちらからIAMのページに飛んでください。
サイドバーの
ユーザー
→ユーザーを追加
をクリックしてAWS CLI用のユーザーを追加します。
ユーザー名はわかりやすいように
aws-cli
としておきます。アクセスの種類はCLIからなので、
プログラムによるアクセス
にチェックを入れます。次のステップに進みます。
アクセス権限の付与は後ほどするので、そのまま次のステップへ。
特にタグで管理をしていないので、そのまま次のステップへ。
アクセス権限を飛ばしたのでWarningが出ていますが、後ほど追加するのでそのまま次のステップへ。
これでユーザー作成が完了しました。
アクセスキーID
とシークレットアクセスキー
は後ほど使うので、コピーしておいてください。2. AWS CLI をインストール
Homebrewをつかって AWS CLI をインストールします。
$ brew install awscliインストールが問題なくされたか確認します。
$ aws --version aws-cli/2.0.0 Python/3.8.1 Darwin/19.3.0 botocore/2.0.0dev4バージョンが表示されればokです。
3. AWS CLI のデフォルト設定を行う
続いてはAWSへのアクセス権限の付与とデフォルト情報を入力していきます。
aws configure
を入力すると項目が4つ表示されるので、順に入力していきます。$ aws configure AWS Access Key ID [None]: ********* AWS Secret Access Key [None]: ****************** Default region name [None]: ap-northeast-1 Default output format [None]: json
AWS Access Key ID
先程作成したユーザーのアクセスキーID
AWS Secret Access Key
先程作成したユーザーのシークレットアクセスキー
Default region name
使用するリージョン名(東京: ap-northeast-1)
Default output format
アウトプットの表示形式(jsonやtextなど)4. AWS CLI の設定を確認する
それぞれ設定ファイルを
cat
で確認します。下記のような表示になれば問題ありません。
$ cat ~/.aws/credentials [default] aws_access_key_id = ********* aws_secret_access_key = ****************** $ cat ~/.aws/config [default] region = ap-northeast-1 output = json変更する場合やユーザーを追加したい時は、上記ファイルに追記すれば可能です。
詳しくはAWS CLI の設定をご覧ください。
AWS EB CLIのインストール・セットアップ
AWS EB CLI をインストール
Elastic Beanstalk用のCLIをインストールします。
$ brew install awsebcli正しくインストールされたか、確認しましょう。
$ eb --version EB CLI 3.17.1 (Python 3.8.2)バージョンが表示されたらインストール完了です。
EB のアクセス権限を付与する
CLI上からElastic Beanstalkを操作できるようにアクセス権限を付けていきましょう。
1. EBアクセス権限のグループを作成する
まずはElastic Beanstalkのアクセス権限をつけたグループを作っていきます。
AWS: IAM から
グループ
→新しいグループの作成
をクリック。グループ名に
eb-cli
を入力し、次のステップへ。検索窓に
elasticbeanstalk
と入力すると関連のポリシーが出てきます。
FullAccess
にチェックを入れて、次のステップへ。ポリシーが追加されているか確認し、グループの作成をクリック。
これでElastic Beanstalkのアクセス権限があるグループが作成できました。
2. ユーザーをグループに追加する
続いては冒頭に作ったAWS CLI用ユーザーをグループに追加します。
サイドバーの
ユーザー
→aws-cli
をクリック。
グループ
→ユーザーをグループに追加
をクリック。先程作った
eb-cli
にチェックを入れ、グループに追加をクリック。これでAWS CLI用ユーザーがグループに追加され、EB CLIからElastic Beanstalkにアクセスできるようになりました。
Railsアプリの用意・事前準備
Railsアプリを用意する
必要に応じてRailsのアプリを用意してください。
Rubyは2.6.5を使用してください。
EC2でのRubyのVersionが2.6.5のため、異なるとエラーが出ます。
自分の各種versionRuby: 2.6.5 Rails: 5.2.4.1 Bundler: 2.1.4自分はシンプルなscaffold構成で作成したものを用意しました。
5.2系統を普段使っているのでRailsのバージョン指定しています。ご自身の環境によって変更してください。
$ bundle exec rails _5.2.4.1_ new eb_sample_app -d postgresql $ cd eb_sample_app $ bundle exec rails g scaffold user name:string $ bundle exec rails db:create $ bundle exec rails db:migrateサーバーを立ててみて問題なくアプリが作成できているか確認します。
$ bundle exec rails s
localhost:3000/users
を開いて、下記のようなサイトが開けば問題ありません。このままではトップページになにも表示されないので、
routes.rb
にrootを追加します。Rails.application.routes.draw do root 'users#index' # << rootを追加 resources :users # For details on the DSL available within this file, see http://guides.rubyonrails.org/routing.html end
localhost:3000
を開いてusers
と同じページが表示されれば設定完了です。Rails Serverはこれ以上使わないので、落としておきます。
この時点でコミットしておきます。
~/eb_sample_app$ git add . $ git commit -m "first commit"デプロイの準備をする
eb init で初期設定を行う
eb init
を入力して初期設定をしていきます。アプリのトップディレクトリで行ってください。
~/eb_sample_app$ eb initいつくかの項目を入力して設定します。
実行中に
ERROR: NotAuthorizedError
が出たら?設定中に
ERROR: NotAuthorizedError
が出たらアクセス権限エラーになっています。ERROR: NotAuthorizedError - Operation Denied. User:arn:aws:iam::476091318231:user/aws-cli is not authorized to perform:elasticbeanstalk:CreateApplication on resource: arn:aws:elasticbeanstalk:ap-northeast-1:476091318231:application/eb_sample_appIAMの設定が有効になるには3~5分ほどかかるので、コーヒーブレイクでもはさみましょう。
10分くらいまってもエラーならIAMの設定が間違えているので、再度IAM設定を行ってください。
それでは入力を進めていきます。
使用するリージョンは東京リージョンを使うので、
9) ap-northeast-1 : Asia Pacific (Tokyo)
の9
を入力Select a default region 1) us-east-1 : US East (N. Virginia) 2) us-west-1 : US West (N. California) 3) us-west-2 : US West (Oregon) 4) eu-west-1 : EU (Ireland) 5) eu-central-1 : EU (Frankfurt) 6) ap-south-1 : Asia Pacific (Mumbai) 7) ap-southeast-1 : Asia Pacific (Singapore) 8) ap-southeast-2 : Asia Pacific (Sydney) 9) ap-northeast-1 : Asia Pacific (Tokyo) 10) ap-northeast-2 : Asia Pacific (Seoul) 11) sa-east-1 : South America (Sao Paulo) 12) cn-north-1 : China (Beijing) 13) cn-northwest-1 : China (Ningxia) 14) us-east-2 : US East (Ohio) 15) ca-central-1 : Canada (Central) 16) eu-west-2 : EU (London) 17) eu-west-3 : EU (Paris) 18) eu-north-1 : EU (Stockholm) 19) ap-east-1 : Asia Pacific (Hong Kong) 20) me-south-1 : Middle East (Bahrain) (default is 3): 9使用するアプリケーションを選択します。
[ Create new Application ]
を選択。※ 初回作成だと
[ Create new Application ]
のみSelect an application to use 1) rails-eb 2) [ Create new Application ] (default is 2): 2ElasticBeanstalkのコンソール上でのアプリ名です。
特に変更がなければ、なにも入力せず空でエンター。
Enter Application Name (default is "eb_sample_app"):自動的にコードを解析して、使用する言語を提案してくれます。
Rubyで良いので、空でエンター。
It appears you are using Ruby. Is this correct? (Y/n):
- 使用するプラットフォームとバージョンを選択
RailsのデフォルトであるPumaで構築したいので、
2) Ruby 2.6 (Puma)
の2
を入力※ Rubyのバージョンは使用しているものを選んでください。
Select a platform version. 1) Ruby 2.6 (Passenger Standalone) 2) Ruby 2.6 (Puma) 3) Ruby 2.5 (Passenger Standalone) 4) Ruby 2.5 (Puma) 5) Ruby 2.4 (Passenger Standalone) 6) Ruby 2.4 (Puma) 7) Ruby 2.3 (Passenger Standalone) 8) Ruby 2.3 (Puma) 9) Ruby 2.2 (Passenger Standalone) 10) Ruby 2.2 (Puma) 11) Ruby 2.1 (Passenger Standalone) 12) Ruby 2.1 (Puma) 13) Ruby 2.0 (Passenger Standalone) 14) Ruby 2.0 (Puma) 15) Ruby 1.9.3 (default is 1): 2
- CodeCommit(AWSが提供してるGitHubのようなもの)を使うかどうか?
使わないので、そのまま空でエンター。
Do you wish to continue with CodeCommit? (y/N) (default is n):
- インスタンスにSSHで接続するかどうか?
接続するので、そのまま空でエンター。
Do you want to set up SSH for your instances? (Y/n):
- 使用するキーペアを設定します。
すでにキーペアを持っている人は、空のままエンター。
初めての人は
[ Create new KeyPair ]
のみなので、作成に進んでいきます。# 作成済 Select a keypair. 1) ec2-keypair 2) [ Create new KeyPair ] (default is 1): # 初めての人 Select a keypair. 1) [ Create new KeyPair ] (default is 1):
Create new KeyPair
に進むとSSHで接続するキーペアを作成していきます。キーペアの名前を付けていきます。
好きな名前を付けてください。
Type a keypair name. (Default is aws-eb): aws-eb公開鍵と秘密鍵が作成されました。
続いて、鍵にパスワードをつけていきます。
空で入力するとパスワードなしで発行されます。Generating public/private rsa key pair. Enter passphrase (empty for no passphrase): Enter same passphrase again:下記のような表示になれば作成完了です。
The key fingerprint is: SHA256:xxxxxxxxxx aws-eb The key's randomart image is: +---[RSA 2048]----+ | | | | | . | | . + | | = * S | | o B E . | |o.+ . + . | |O= =o+.=.+ | |X++ .oo. | +----[SHA256]-----+もう一度パスワード入力を求められるので入力します。
Enter passphrase: WARNING: Uploaded SSH public key for "aws-eb" into EC2 for region ap-northeast-1.EC2へのSSH接続が確認されキーペアの連携ができました。
これで初期設定が完了です。
.elasticbeanstalk
フォルダが作成され、中にconfig.yml
という設定ファイルが作成されました。
config.yml
の中身は以下のようになっています。~/eb_sample_app/.elasticbeanstalk/config.ymlbranch-defaults: master: environment: null group_suffix: null global: application_name: eb_sample_app branch: null default_ec2_keyname: aws-eb default_platform: Ruby 2.6 (Puma) default_region: ap-northeast-1 include_git_submodules: true instance_profile: null platform_name: null platform_version: null profile: null repository: null sc: git workspace_type: Application
eb create
の前に各種問題への対処続いて
eb create
をするのですが、そのまま実行すると3つのエラーが発生します。それぞれどんなエラーが発生するのか解説し、事前に対応します。
1. bundlerが古い問題
そのまま実行すると自動で実行される
bundle install
でエラーがでます。エラーの内容は指定されているBundlerが無いぞ!って言われてます。
ERROR [Instance: i-02e2bc303363c3671] Command failed on instance. Return code: 1 Output: (TRUNCATED)...your system, run `bundle update --bundler`. To install the missing version, run `gem install bundler:2.1.4`これは初期に生成されるEC2環境のBundlerのバージョンが1.16.0のため、最新のBundleが無いんですね。
[ec2-user@ip-172-31-2-55]$ bundle -v Bundler version 1.16.0SSHで接続して
gem install bundler:2.1.4
でインストールしてもいいのですが、それだと毎回設定が必要です。しかもこのままではAuto Scalingで2台目が立ち上がったときも設定が必要で意味がありません。
ElasticBeanstalkには初回にコマンドを実行する設定があるので、そちらで必要となる処理を記載していきます。
gem install bundlerの実行設定をする
アプリのトップディレクトリに
.ebextensions
というファイルを作成します。
.
は必要なので気をつけてください!このファイルに
~.config
というファイルを作成すると実行時に読み込んで実行してくれます。~/eb_sample_app$ mkdir .ebextensions $ cd .ebextensions $ touch gem_install_bundler.config中身を下記の内容で作成します。
~/eb_sample_app/.ebextensions/gem_install_bundler.configfiles: "/opt/elasticbeanstalk/hooks/appdeploy/pre/09_gem_install_bundler.sh" : mode: "000775" owner: root group: users content: | #!/usr/bin/env bash EB_SCRIPT_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k script_dir) EB_APP_STAGING_DIR=$(/opt/elasticbeanstalk/bin/get-config container -k app_staging_dir) . $EB_SCRIPT_DIR/use-app-ruby.sh cd $EB_APP_STAGING_DIR gem update --system gem install bundler -v 2.1.4内容は、自動で実行される
bundle install
の前に
gem update --system
gem install bundler -v 2.1.4
を実行するコードになります。
gem install bundler -v 2.1.4
の2.1.4
はご自身のBundler versionを指定してください。
Gemfile.lock
の一番下に書いてあるBUNDLED WITH
に合わせないとエラーになります。Gemfile.lockBUNDLED WITH 2.1.43.
master.key
が無い問題続いては
rails credentials:edit
が発生します。ERROR [Instance: i-012e1680a4956ac39] Command failed on instance. Return code: 1 Output: (TRUNCATED)...tring with `rails credentials:edit`ElasticBeanstalkにデプロイすると自動でproduction環境になります。
その際に
config/master.key
もしくはRAILS_MASTER_KEY
を参照しているのですが、
config/master.key
は秘密鍵なのでgitignore
でgitにcommitされないようになっています。
この情報がないためエラーになります。詳しくはこの記事では触れないため、下記のサイトを参照してください。
Rails5.2から追加された credentials.yml.enc のキホン
Serverに環境変数である
RAILS_MASTER_KEY
を設定しましょう。まずは
config/master.key
を開きます。~/eb_sample_app/config/master.keyda7xxxxxxxxxxxxxxxxxdf1b1de中に文字の羅列があるので、そちらをコピーしておいてください。
eb create
時に--envvars
のオプションをつけると環境変数を設定できます。
eb create
実行する時に以下のコマンドを付ければ解決です。
※まだ実行しないでください。eb create --envvars RAILS_MASTER_KEY=da7xxxxxxxxxxxxxxxxxdf1b1de複数つける場合はカンマ区切りでつけることができます。
--envvars key=value,key2=value2,key3=value33. DBが無い問題
続いてのエラーはDBがなくて
db:migrate
が出来ないよ!っていうエラーです。ERROR [Instance: i-048e3c74bf17b2499] Command failed on instance. Return code: 1 Output: (TRUNCATED)...ly and accepting connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"? Tasks: TOP => db:migrateElasticBeanstalkでは、RDSの立ち上げはオプションなので
eb create
にDB作成するオプションを付けて自動で作成されるようにします。
※まだ実行しないでください。eb create -db.engine postgres \ -db.user ebroot -db.pass testpassword
-db.engine postgres
DBのエンジンを決めます。mysql
postgres
など設定できます。
-db.user ebroot
DBのデフォルトユーザー名です。
お好きな名前を付けてください。デフォルトはebroot
です
-db.pass testpassword
DBのデフォルトユーザーのパスワードになります。
好きなパスワードを入れてください。Elastic Beanstalkへデプロイ
eb create
でアプリケーションを作成する準備が整いました。
eb create
を実行しましょう。以下のコマンドを丸々コピーして実行してください。
※オプションの値は適宜自分のものに変更してください。~/eb_sample_appeb create -db.engine postgres \ -db.user ebroot -db.pass testpassword \ --envvars RAILS_MASTER_KEY=da7xxxxxxxxxxxxxxxxxdf1b1de実行すると4つの項目を聞かれます。
すべてデフォルトで良いので、空でエンターを4回押します。
Enter Environment Name (default is eb-sample-app-dev): Enter DNS CNAME prefix (default is eb-sample-app-dev): Select a load balancer type 1) classic 2) application 3) network (default is 2): Would you like to enable Spot Fleet requests for this environment? (y/N):するとなにやら実行されます。
EC2やらなんやら立ち上げていて、10分ほどかかるので2度目のコーヒーブレイクをお楽しみください。
Creating application version archive "app-f738-200316_020752". Uploading eb_sample_app/app-f738-200316_020752.zip to S3. This may take a while. Upload Complete. An environment with that name already exists. Enter Environment Name (default is eb-sample-app-dev2): Environment details for: eb-sample-app-dev Application name: eb_sample_app Region: ap-northeast-1 Deployed Version: app-f738-200316_020752 Environment ID: Platform: arn:aws:elasticbeanstalk:ap-northeast-1::platform/Puma with Ruby 2.6 running on 64bit Amazon Linux/2.11.3 Tier: WebServer-Standard-1.0 CNAME: Updated: 2020-03-15 17:08:44.727000+00:00 Printing Status: 2020-03-15 17:08:42 INFO createEnvironment is starting. 2020-03-15 17:08:44 INFO Using elasticbeanstalk-ap-northeast-1-476091724641 as Amazon S3 storage bucket for environment data. 2020-03-15 17:09:06 INFO Created target group named: arn:aws:elasticloadbalancing:ap-northeast-1:476091724641:targetgroup/awseb-AWSEB-1EYCMUPNKMX61/ccc7435548d76a87 2020-03-15 17:09:06 INFO Created security group named: sg-09f51d827976f2e04 . . .ログを見ると作成されてるのはこれらのようです。
- Environment
- Target Group
- Security Group
- Auto Scaling
- RDS Database
- Load Balancer
- EC2 Instances
- CloudWatch Alarm
時間がある方は、なにが作成されているのかチェックしてみてください。
時間がかかって
ERROR: TimeoutError
になった人はeb events -f
を実行すれば再度確認できます。ERROR: TimeoutError - The EB CLI timed out after 15 minute(s). The operation might still be running. To keep viewing events, run 'eb events -f'. To set timeout duration, use '--timeout MINUTES'.$ eb events -f
Successfully
が表示されれば完了です!2020-03-15 17:14:00 INFO Successfully launched environment: eb-sample-app-devデプロイしたアプリをひらく
eb open
を実行すると作成したアプリを開くことができます。実行してみましょう。
$ eb openブラウザでアプリが開けば成功です。
実際にユーザーを作成して成功するか試してみましょう。
New User
→nameを入力
→Create User
Successfullyと出れば成功です!
トップに戻ると作成されていることが確認できます。
AWS: ElasticBeanstalkを確認すると作成されたアプリケーションが確認できます。
緑色になっていると問題なく動作している状態です。
赤色などになっているとなにか問題が起きています。作成したアプリケーションを開いてみましょう
作成したアプリケーションの情報が表示されます。
URLの部分が今回作成されたアプリケーションのURLです。
サイドバーの設定を開くとインスタンスやロードバランサーの設定を確認することができます。
再度デプロイをする方法
ファイルを更新したら、commitして
eb deploy
をすれば
自動でファイルを転送されデプロイが完了します。$ git add . $ git commit -m "Add ..." $ eb deployデプロイがこんなに簡単にできるなんて最高!!
SSH接続をする方法
EC2にSSH接続するには
eb ssh
を実行するとSSH接続できます。$ eb sshRailsアプリは
/var/app/current/
に入っているので、気になる人はチェックしてみてください。[ec2-user@ip-172-31-1-95]$ cd /var/app/current/ $ ls Gemfile Rakefile config lib public tmp Gemfile.lock app config.ru log storage vendor README.md bin db package.json testエラーで表示できなかった場合
エラーなどで表示できなかった方は、ログをチェックしてみてください。
$ eb logsまとめ
今回はElastic Beanstalkを使って簡単にEC2にデプロイを試してみました。
VPC、RDSやオートスケール、ロードバランサーなど複雑な設定を知らなくても
スタンダードなインフラ設計で簡単につくれるElastic Beanstalkはとても良いと思いました。ただ、VPCや中でなにを行われているのかわからないため、インフラを理解する観点として
同じ設計を手動で立てれるようになることも重要だと思います。全体像を掴む方法として、まずはElastic Beanstalkを使ってみることをおすすめします!
次回の記事ではSSL化、RDSを独立させる方法、Dockerを使ったデプロイなどを解説していこうと思います。
参考にさせていただいたサイト
AWSのElastic Beanstalkでナウい構成のWebアプリを構築しよう! - Qiita
Rails5.2から追加された credentials.yml.enc のキホン - Qiita
Ruby on Railsの環境構築をElastic Beanstalkで行う - Qiita
RailsアプリケーションをElastic Beanstalkにデプロイするまで - Qiita
【2020年版】RailsアプリをElasticBeanstalkでデプロイするまでの手順 | ニートエンジニア
Elastic Beanstalk: can't find gem bundler (>= 0.a) - Stack Overflow
EB CLI コマンドリファレンス
- 投稿日:2020-03-16T18:52:10+09:00
MySQLが起動できない(動かなくなった) という地獄のエラー(ERROR! The server quit without updating PID file と Fatal error: Can't open and lock privilege tables: Table 'mysql.user' doesn't exist)
背景
phpの学習中にmysqlをいじっていましたw
急にmysqlが起動できなくなり、エラー解消にほぼ半日躓いてしまったので、
その解決策と試したことを記事としてのせたいと思う!!mysqlでのエラー文との遭遇
エラー内容一覧
mysqlを起動を確かめる
mysql.server start Starting MySQL . ERROR! The server quit without updating PID file (/usr/local/var/mysql/ユーザーMBP.pid).意味はpidファイルを更新せずに終わったよ!ってエラー?
すいません、、、意味がわかりません(涙)pidファイルとは?
Pidファイルには、特定のプログラムのプロセスID(番号)が含まれています。たとえば、Apache HTTPDはメインプロセス番号をpidファイル(通常のテキストファイル、それ以上のもの)に書き込み、後でそこに含まれる情報を使用して停止します。 cat filename.pid | xargs killを使用して、その情報を使用して自分でプロセスを強制終了することもできるみたいです。
ググって試したこと!
①権限関係
権限確認すると「_mysql:_mysql」だったので、自分:adminに変更した。
chown -R [ユーザ名] /usr/local/var/mysqlうまくいかず。
②エラーログ確認しにいく
cd /usr/local/var/mysql ls (lsコマンドでmysqlディレクトリの中身を確認する) その中に (ユーザー)MBP.err というファイルがあるので cat (ユーザー)MBP.err (catコマンドでファイルの中身を確認) エラーログの中身に 2020-03-16 17:32:04 25993 [ERROR] Fatal error: Can't open and lock privilege tables: Table 'mysql.user' doesn't exist調べてみると、インストール時に mysql_install_db が実行されるが、ディレクトリがわからない状態らしい。
インストール場所とユーザ名を指定して明示的に実行すると良さそうらしいですが、、mysql_install_db --datadir=/var/lib/mysql --user=mysqlうまくいかず...
参考ページ
https://qiita.com/840_/items/06f32fecbe57c3fdf5ec③最終手段 全てをアンイストール!!
よく見るとmysql、mysql@5.6、mysql@5.7やらいっぱいmysqlが存在してしまっていたので全てアンインストール!
の前に
*実行前に
そのまま解決手順を実行してしまうと、mysqlのデータが削除されてしまいます。
以下の手順を実行し、バックアップを行ってください!!$ brew services stop mysql mysqlを一旦停止 $ cp -pr /usr/local/Cellar/mysql /適当な場所/mysql_backup これで、mysqlのデータバックアップ。brew uninstall mysql brew uninstall mysql@5.6 brew uninstall mysql@5.7まずはmysqlをアンインストール!
次にlocal配下のmysqlを全て削除する
$ rm -rf /usr/local/mysql $ rm -rf /Library/StartupItems/MYSQL $ rm -rf /Library/PreferencePanes/MySQL.prefPane $ rm -rf /Library/Receipts/mysql-.pkg $ rm -rf /usr/local/Cellar/mysql* $ rm -rf /usr/local/bin/mysql* $ rm -rf /usr/local/var/mysql* $ rm -rf /usr/local/etc/my.cnf $ rm -rf /usr/local/share/mysql* $ rm -rf /usr/local/opt/mysqlポイント!
brew uninstall mysqlでは削除できないファイル群を削除するのが大事!
残っているとアンインストールしても解消されないので、すっきり全て削除!mysqlを再インストール
brew install mysql(@__使用するmysqlバージョンを指定)mysqlコマンドをどこからでも実行できるようする
$ echo 'export PATH="/usr/local/opt/mysql/bin:$PATH"' >> ~/.bash_profile mysqlバージョンを指定している場合(mysql@5.6) $ echo 'export PATH="/usr/local/opt/mysql@5.6/bin:$PATH"' >> ~/.bash_profile $ source ~/.bash_profile mysqlのコマンドが打てるか確認する $ which mysql 以下のように表示されれば成功 /usr/local/opt/mysql/bin/mysql最後にmysqlを起動
mysqlの状態を確認するコマンドです $ mysql.server status 以下のように表示されれば成功 SUCCESS! MySQL running (29385)他にもプロセスを確認
$ ps ax | grep mysql 29714 s001 S 0:00.03 /bin/sh /usr/local/Cellar/mysql/8.0.19/bin/mysqld_safe --datadir=/usr/local/var/mysql --pid-file=/usr/local/var/mysql/ユーザMBP.pid 29825 s001 S 0:05.17 /usr/local/Cellar/mysql/8.0.19/bin/mysqld --basedir=/usr/local/Cellar/mysql/8.0.19 --datadir=/usr/local/var/mysql --plugin-dir=/usr/local/Cellar/mysql/8.0.19/lib/plugin --log-error=ユーザMBP.err --pid-file=/usr/local/var/mysql/ユーザMBP.pid 29837 s001 S+ 0:00.00 grep mysqlok問題ないですね!
参考
https://teratail.com/questions/199085これでようやく解決してくれました!
本当に強引な方法ではありますがうまくいきました!
最後に
本当によく躓くエラーなので反省をとこれからの課題として記事として残しておきます!!
- 投稿日:2020-03-16T17:22:26+09:00
【Rails】setupメソッド
setupメソッド
テストファイル上で記載するメソッドで、各テストが走る前に実行されるメソッド。
またsetupメソッドでインスタンス変数を定義すれば全てのテスト内で、そのインスタンス変数が使用可能になります。実行例
test/models/user_test.rbrequire 'test_helper' class UserTest < ActiveSupport::TestCase def setup @user = User.new(name: "Example User", email: "user@example.com") end test "should be valid" do assert @user.valid? end endこうすることでテストである
should be valid
が走る直前にset up
が実行されるようになります。
assert @user.valid?
の@user
はset up
から持ってきています。
- 投稿日:2020-03-16T17:11:30+09:00
Ruby on RailsとAlexaで、めちゃんこ操作しにくいゲーム作ってみた。
初めに
この記事では、Ruby on Railsを使用して、Alexaによる音声認識で操作することができる3×3のスライドパズル作成についてかきました。
Ruby on Railsや、今回サーバーの実装として利用したngrokの導入方法についての説明は省いておりますのでご了承ください。
今回、技術的説明は極力省き、実装面のみの記事としているため、主な技術要件の参考記事は以下を参照ください。
Alexaコンソールについて
Alexaコンソール(Alexaスキル)では、どのような情報をサーバー(Ruby on Rails側)にPOSTするのか書き込みます。
クリスマスプレゼントに、Amazon Echoはいかが?〜Alexaスキルを自作してみよう〜 - QiitaActionCableについて
ActionCableは、Railsに比較的新しく備え付けられた非同期処理を実装するための方法です。WebSocketとの連携を補助するツールと筆者は捉えています。
最短で作るActionCableチャットアプリ - Qiitangrokについて
こんなの説明いらんやろ!と言われそうですが一応。。
【3分で出来る】ngrokでデプロイをしてみよう! - Qiitangrokを利用するための下準備
#config/environments/development.rbconfig.hosts << '.ngrok.io'上記を追加し、ngrokによるホスティングを許可してあげればOK
ActionCableを利用するための下準備
これは簡単です。
bash$ rails g channel talks
このコマンドで、WebSocketに関するファイルが生成されます。
今回はコントローラー名も一括してtalksにしています。#app/channels/talks_channel.rbclass TalksChannel < ApplicationCable::Channel def subscribed stream_from "some_channel" end def unsubscribed # Any cleanup needed when channel is unsubscribed end def speak end endsome_channelというケーブル名にしましょう。
Railsのルーティング設定
以下を記載します。
#config/routes.rbRails.application.routes.draw do root 'talks#index' resources :talks, only: [:create, :index] endカレントディレクトリをプロジェクト内にし、以下のコマンドでルーティングを確認できます。
bash$ rails routes
POST /talks(.:format)Alexaに話しかけた内容は、エンドポイントで指定されたURLにPOSTで送られます。/talksをAlexaコンソール上でエンドポイントに設定します。
続いて、コントローラーです。
#app/controllers/tasks_controller.rbclass TalksController < ApplicationController skip_before_action :verify_authenticity_token # POST /talks def create request = AlexaRubykit::build_request(params) #paramsはAlexaから送られるJSONデータ request_word = request.slots[:message][:value] response = AlexaRubykit::Response.new response.add_speech("#{request.slots[:message][:value]}に移動します.") message = @@board.slide(request_word) ActionCable.server.broadcast("some_channel",message) render json: response.build_response end def index @@board = Board.new end end #0は空白 class Board def initialize @@panels = [ [1,3,6], [0,7,2], [5,8,4] ] end #入れ替える要素の番号を引数として配列で受け取る index → [j,i] def swap(index1,index2) tmp = @@panels[index1[0]][index1[1]] @@panels[index1[0]][index1[1]] = @@panels[index2[0]][index2[1]] @@panels[index2[0]][index2[1]] = tmp end def slide(dir) brank_index = Array.new(2) @@panels.each_with_index do |panel,j| i = panel.find_index { |value| value == 0} if i != nil brank_index = [j,i] break end end case dir when '上', 'ウェイ' if brank_index[0] != 2 self.swap(brank_index,[brank_index[0]+1,brank_index[1]]) end when '下' if brank_index[0] != 0 self.swap(brank_index,[brank_index[0]-1,brank_index[1]]) end when '左' if brank_index[1] != 2 self.swap(brank_index,[brank_index[0],brank_index[1]+1]) end when '右' if brank_index[1] != 0 self.swap(brank_index,[brank_index[0],brank_index[1]-1]) end end @@panels end end#Gemfileに以下を追加gem 'alexa_rubykit', '1.3.1'一気に長いコードが出てきたので少し説明します。
まず、Boardクラスは、初期化やAlexaからのメッセージによって盤面を移動させたりする関数(slide())から構成されています。request = AlexaRubykit::build_request(params) request_word = request.slots[:message][:value]この部分では、Alexaから送られたJSONがparamsに入っており、AlexaRubyKitで受け取り、目的とする単語(今回の場合はスライドパズルなので「上」や「下」)をrequest_wordに渡します。
response = AlexaRubykit::Response.new response = AlexaRubykit::Response.new response.add_speech("#{request.slots[:message][:value]}に移動します.") ~~ render json: response.build_responseこの部分では、Alexaに応答させる言葉をadd_speechに持たせて、renderでAlexaに送っています。
message = @@board.slide(request_word) ActionCable.server.broadcast("some_channel",message)Alexaから受け取った言葉をslide関数に渡して、盤面を更新していきます。そして更新された盤面をsome_channelというActionCableを使ってクライアント側にブチ飛ばしていますね。
クライアント側での処理
先ほどブチ飛ばした内容は、talks_channel.jsで受け取ります。
#javascript/channels/talks_channel.jsimport consumer from "./consumer" consumer.subscriptions.create("TalksChannel", { connected() { // Called when the subscription is ready for use on the server }, disconnected() { // Called when the subscription has been terminated by the server }, received(data) { // Called when there's incoming data on the websocket for this channel let txt = ''; data.forEach((value) => { txt += '<div class="line">'; value.forEach((e) => { if (e == 0){ txt += '<div class="empty-box" ></div>'; }else{ txt += '<div class="box" ><p>' + e + '</p></div>'; }; }); txt += '</div>' }); document.querySelector("#display").innerHTML = txt; console.log(txt); }, speak: function() { return this.perform('speak'); } });こんな感じで、クライアント側のjsをいじると、画面を更新することなくスライドパズルが動くというわけです。
あとはHTMLとCSSを適当にいじって完成です。
なんとも春らしい見た目。最後に
AlexaRubyKitってなかなか日本語のドキュメントもないしかなり苦戦したので、これからAlexaを使ってアプリケーションを作ろうとする方の手助けになればいいなと思います。
ActionCableは筆者的に今熱いのでどんどんプロダクトに使って行きたいですね。
これからも励んでいきますので、よろしくお願いします。
- 投稿日:2020-03-16T16:57:16+09:00
部分テンプレートとは?
部分テンプレートってなんなの??
部分テンプレートとは・・・
複数のビューファイルの中で使われている部分を一つのビューファイルとして管理すること。
つまりどういうことかというと複数回使うビューをテンプレート化してしまうことで冗長な記述が必要なくなるというとっても便利かつ簡単なテクニックです。
部分テンプレートを作成する
部分テンプレートのビューを作成するときの注意点としてビューファイルのファイル名の先頭の部分に
_ (アンダーバー)
をつける必要があります。
例えば、呼び出したい部分テンプレートファイルがheader.html.erb
だとすると、
_header.html.erb
と書き換えましょう。部分テンプレートの呼び出し方
当たり前ですが、実際に部分テンプレートを呼び出すためのメソッドがあります。それが
renderメソッド
です._header.html.erbrender 'ファイル名' #'ファイル名'で部分テンプレートの呼び出し render partial: 'ファイル名' #partialはつけてもつけなくても可このように記述していくことで部分テンプレートが使用できて、同じようなコード再度記述していく必要がなくなります!便利ですよね。
haml
で書くとどうなるのかというと_header.html.haml= render 'ファイル名' #=でくくってあげちゃうだけ
renderメソッド
にはもっと活用できるオプションがあるみたいなので詳しく知りたい方は検索してみましょう(優秀なエンジニアに丸投げ)以上です。至らない点があればコメントお願いします。
- 投稿日:2020-03-16T16:44:42+09:00
FontAwesomeとは
- 投稿日:2020-03-16T16:40:26+09:00
Hamlとは
Haml
HTMLよりも簡単に書くためのビューテンプレートエンジンです。
Hamlを使用することで、「綺麗に」、「読みやすく」、「生産的に」ビューを作成することができます。HamlのGem
Haml記法を可能にするhaml-railsというGemが提供されています。このGemをプロジェクトにインストールすることで簡単にHamlを導入することができます。また、既存のerbファイルをHaml記法に変換することもできます。
Gemfileの一番下に記述します。gem "haml-rails"bundle installターミナル
$ rails haml:erb2hamlでerbのファイルをhamlに変換します。
Hamlの記述(タグ)その1
【例】HTMLの場合
<form> <input type="submit"> </input> </form>【例】Hamlの場合
%form %input{type: "submit"}Hamlの記述(タグ)その2
【例】HTMLの場合
<% messages.each do |message| %> <%= @message.content %> <% end %> <%= link_to messages_path, class:"contents" do %> <%= @message.name %> <% end %>【例】Hamlの場合
- messages.each do |message| = message.content = link_to messages_path, class:"contents" do = @message.nameHamlの記述(クラス)
【例】HTMLの場合
<div class="top"> </div> <div class="main center"> </div> <form class="down"> </form>【例】Hamlの場合
.top .main.center %form.down
- 投稿日:2020-03-16T16:05:02+09:00
BEMとは
BEM
多くの開発者が取り入れているCSS設計(CSSを記述する時のルール)です。BEMは、厳格なクラスの命名規則が特徴です。BEMはBlock、Element、Modifierの頭文字を取ったもので、ページを構成する要素をBlock、Element、Modifierのどれかに当てはめてクラスを命名します。
クラスの命名が簡単になる
Block、Element、Modifierのみでクラスを命名することで、クラス名に悩むことがなくなります。
要素の再利用がしやすくなる
共通の要素を別の場所で再利用しようとしても、要素がHTMLに依存していると同じCSSを2つ書かなければなりませんでした。しかし、BEMを使用することで、クラスの命名がHTML構造に依存しなくなります。
HTML構造に依存しないことで、要素の再利用がしやすくなります。Block
ある要素の大元となるブロック要素です。Blockの命名には名詞を使用します。ElementやModifierは、Blockを起点に命名されます。
Element
Blockに属する子要素です。1つ以上のElementによって、Blockは構成されています。Elementの命名には名詞を使用します。
Modifier
Blockまたは、Elementに特別な修飾をする要素です。Modifierの命名には形容詞を使用します。
命名規則
BlockとElementをつなぐ場合は、アンダースコア2つでつなぎます。
Modifierにつなぐ場合は、ハイフン2つでつなぎます。
【例】XXXX.htmlnav class='HeaderNav'> <ul class='Menu'> <li class='Menu__list'>TOP</li> <li class='Menu__list'>CONTACT</li> <li class='Menu__list Menu__list--backBlack'>ABUOT US</li> <li class='Menu__list'>SERVICE</li> </ul> </nav>navはヘッダーのナビゲーションメニューなので、クラス名をHeaderNavとしました。
このようにクラス名の単語数が2つ以上の場合はキャメルケースまたはスネークケースでつなぎます。
ulはheader-navの子要素ですが他のヘッダーメニュー以外の部分でも使用したいので、クラス名をMenuとしました。
liはMenuの子要素なので、クラス名をMenu_listとしました。
liのうちABOUT USだけは背景色を黒くしたいので、クラス名をMenu_list--backBlackとしました。
Modifierはこのように特定の部品を修飾したい時に使用します。
上記に対したSassXXXX.scss.Menu { list-style: none; &__list { background-color: #3BD1EC; color: #FFF; float: left; font-size: 30px; padding: 2% 1%; text-align: center; width: 23%; &--backBlack { background-color: #000; color: #3BD1EC; } } }Modifierを使用した部分だけ背景色を黒くできました。
- 投稿日:2020-03-16T15:02:55+09:00
Sassのファイルとフォルダ
index.html
このファイルに書かれたものがブラウザに表示されます。
style.css
htmlファイルでstyle.cssファイルを読み込むことでスタイルを適用させます。
style.cssファイルを直接編集するのではなく、sassコマンドを実行することでstyle.cssファイルを作成・更新します。stylesheetsフォルダ
すべてのscssファイルを管理するフォルダです。
scssファイルを追加する場合は、stylesheetsフォルダ内に作成します。style.scss
このファイルですべてのscssファイルを@importで読み込むことで、一つのsassファイルに統合します。
【例】@importを使用してscssファイルを読み込みます@import "reset"; /*_reset.scssを読み込む */ @import "./config/XXXX"; /* configフォルダの中の_XXXX.scssを読み込む */_reset.scss
ブラウザによって初めからcssがそれぞれのhtmlに設定されています。
そのCSSによって、意図しないデザインになってしまうことがあります。
そのようなことを防ぐために、初めにブラウザごとのCSSをすべてリセットします。
HTML5 Doctor Reset CSS 2.0
sanitize.css
などがあります。configフォルダ
プロジェクトの設定ファイルや、scssで使用する変数を定義するファイルなどを管理するフォルダです。
mixinフォルダ
scss内で使用するmixinファイルを管理するフォルダです。
modulesフォルダ
モジュールを管理するためのフォルダです。
モジュールとは、いくつかの要素をまとめた部品の集合という意味です。
ヘッダー、フッターのような用途ごとに分けることができます。
モジュールを使うことでまとまったCSSを独立したものとして管理することができます。vendorフォルダ
ライブラリのファイルを管理するフォルダです。
ライブラリとはあらかじめCSSが書かれたファイルです。overrideフォルダ
vendorフォルダに格納してある外部のライブラリを上書きするためのscssファイルを管理するフォルダです。
- 投稿日:2020-03-16T13:54:54+09:00
Sass
Sassとは
SassとはCSSの機能を拡張した言語です。Sassを使用することでCSSを効率的に書けるようになります。CSSを簡潔に書けるだけではなく、CSSの中で変数を使ったり、計算を行うことなどができます。
Sassファイル
Sassは通常のCSSファイルには記述することができません。反対にSassファイルにCSSを記述することはできます。Sassを扱うファイルの拡張子は.sassと.scssの2種類があります。どちらもSassのファイルとなりますが記法が大きく異なります。
.sass拡張子
Sassファイルでは最初に作られたSassの記法を扱うことが出来ます。Sassは波カッコの省略やセミコロンが不要などシンプルな記法です。
【例】Sass.body p color: #333 font-size: 10px font-weight: normal strong color: red font-weight: bold.scss拡張子
.sassの後に作られたSassファイルが.scssの拡張子のファイルです。scssはCSSに非常に似た記法でSassの機能を使うことが出来ます.
【例】.body p { color: #333; font-size: 10px; font-weight: normal; strong { color: red; font-weight: bold; } }記述の簡略化
例えば親子関係にあるセレクタを入れ子にして書くことができます。
CSSでは、親の要素から対象要素までのセレクタを何度も書く必要がありますが、Sassはネストさせることで、同じ親のセレクタをまとめることができます。
【例】例えばこんなhtmlがあるとします<div class="block"> <h1 class="title">XXXX</h1> <p class="text">YYYY <span>ZZZZ</span> </div>【例】CSSの場合
.block { background-color: #000; } .block .title { color: #FFF; font-size: 50px; text-align: center; } .block .text { font-size: 10px; color: #FFF; } .block .text span { color: red; font-size: 20px; }【例】sassの場合
.block { background-color: #000; .title { color: #FFF; font-size: 50px; text-align: center; } .text { font-size: 10px; color: #FFF; span { color: red; font-size: 20px; } } }SassではCSSをネスト(入れ子)して記述することができます。ネストして記述することで深い階層になっても親子関係がわかりやすくなり、親要素を複数記述しなくて済みます。
変数や条件分岐といったプログラムのような処理を記述できる
Sassでは、変数を使用することができます。例えばピクセル数やカラーコードなどの何度も使用する値を変数を定義することで、変数名で何度も使用することができます。変数を定義するには、$変数名: 値;のように記述します。
【例】$section-color: rgb(30,30,30); section { background-color: $section-color; }複数のCSSファイルを1つにまとめることができる
Sassではパーシャルという機能を使用することで、複数のSassファイルを1つのCSSファイルとしてまとめることができます。
パーシャル
分割したSassファイルのことです。ファイルを分割することで、機能や内容ごとに管理ができるようになります。一定のルールでファイルを分割して開発することで変更・修正がしやすくなります。
パーシャルファイルを作成するには、ファイル名を(アンダースコア)から始めます。パーシャルファイルを読み込むには、@importファイル名と記述します。
【例】_reset.scssと_header.scssを読み込むとします@import "reset"; /* _reset.scssを読み込む */ @import "header"; /* _header.scssを読み込む */同じ値を使い回すことができる
CSSでは、複数の要素に同じスタイルを適用させる場合、何度も同じスタイルを記述します。しかし、Sassでは変数を使うことによって、同じ値を使い回すことができます。
変数を定義するには、$変数名: 値;で記述します。
【例】$mainYellowColor: #FFEC00; /* #FFEC00という色をmainYellowColorという変数名で定義する */また、mixinという機能を使用することで、同じスタイルをまとめることもできます。
mixin
まとまったスタイルを定義することができる機能です。
変数は値を定義するものですが、mixinはスタイルを定義するものです。
mixinを利用することで、何度も同じスタイルを記述する必要がなくなります。
mixinを定義するには、@mixin mixin名() {}のように記述します。
【例】.clearfix(レイアウトが崩れてしまった際に役立つ機能)を使用します。以下のように_clearfix.scssファイルに定義します。_clearfix.scss@mixin clearfix() { &:after { content: ''; display: block; clear: both; } }&(アンパサンド)は、擬似要素であるafterが適用されているセレクタを指します。以下の例では、&は.menuに相当します。
つまり、擬似要素afterは、.menuに対して適用されているということです。
このmixinの呼び出しは@includeを使用して以下のように記述します。_XXXX.scss.menu { @include clearfix(); ... .menu__list { float: left; ... } }XXXX.scssの記述は以下のSassコードと同じです。
_clearfix.scss.menu { &:after { content: ''; display: block; clear: both; } .menu__list { float: left; ... } }
- 投稿日:2020-03-16T13:03:02+09:00
外部キー制約のついたカラムを削除したい
外部キー制約の付いたカラムを削除するのにプチハマりしたのでまとめます
参考
こちらの記事でマイグレーションについてかなり詳しくまとめられています
マイグレーションの操作をするときは、こちらの記事で該当箇所をざっと読んでから公式ドキュメントに目を通すのが良さそう
https://pikawaka.com/rails/migrationAPIdoc
https://apidock.com/rails/ActiveRecord/ConnectionAdapters/SchemaStatements/remove_index例)ベストアンサー機能
- questionモデル内に、ベストアンサーに選ばれた回答を保存するためのbestカラムがある
- bestカラムには外部キーが設定してある(answersテーブル)
という状況
db/schema.rbcreate_table "questions", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t| t.bigint "best" t.index ["best"], name: "fk_rails_dd35f91b0c" end add_foreign_key "questions", "answers", column: "best"実践
まずはカラム削除用のマイグレーションファイルを作成する
$rails g migration RemoveBestFromQuestions
マイグレーションファイルが生成
db/migrate/xxxx_remove_best_from_questions.rbclass RemoveBestFromQuestions < ActiveRecord::Migration[5.1] def change end endこちらにカラムを削除するための記述を追加していく
外部キーとインデックスを貼っているので、カラムを削除する記述だけではエラーが発生してしまう
それらを削除する記述も必要っぽいdb/migrate/xxxx_remove_best_from_questions.rbclass RemoveBestFromQuestions < ActiveRecord::Migration[5.1] def change remove_foreign_key :questions, :answers remove_index :questions, :best remove_column :questions, :best, :bigint end endこれで
rails db:migrate
を実行すればOK最後に
間違っている部分があれば遠慮なくご指摘ください
- 投稿日:2020-03-16T12:45:10+09:00
[Rails] Mechanizeがファイルディスクリプタを大量に消費してしまう
内容はタイトル通り。
Railsにて、Mysql2のConnectionError出てる場合とか
ファイルディスクリプタを異常に使いまくってる場合はもしかしたら関係あるかも。経緯
お客様に提供しているサービス(Rails,puma)にて
Mysql2::Error::ConnectionErrorが多発してサービスが利用できなくなる障害が発生しました。
詳しくログを追ってみると他にも
Errno::EMFILE (Too many open files @ rb_sysopen ...(略)のようなエラーも発生している様子。
さらに、、、
# ファイルディスクリプタ上限確認 ulimit -n # pumaプロセスのファイルディスクリプタ確認 for i in $(ps aux | grep "[p]uma" | awk '{print $2}'); do sudo ls /proc/$i/fd | wc -l; done上記コマンドでプロセスの開いてるファイル数を確認してみたら
どうやらファイルディスクリプタがいっぱいになっているようだった。原因
実は、ファイルを開いているわけではなくてアプリケーションで使用していた Mechanize というgemにて
外部からデータを取得する際にコネクションを作成していた様子。
(スクレイピングとかするときに使われてるgemらしい。)ファイルディスクリプタでは、ファイルだけでなくコネクションもカウントされるようで
大量のコネクションが削除されずに作成され続けたことで問題が発生した。
(Mysqlも多分コネクション関係?? 詳しい人コメントお願いします。)対応
単純に、コネクションが開いたままになっていることが問題。
閉じてあげる必要がある。Mechanizeのコネクションは以下のメソッドを呼び出すと閉じてくれるらしいので
使用中のコネクションの最後の処理が終わったあたりで呼び出してあげる。Mechanize.shutdownあとは、サーバー再起動などで既存コネクションを消してあげましょう。
- 投稿日:2020-03-16T11:40:38+09:00
AWS EC2 でgit pull origin master ができない時の対処法
はじめに
ローカル環境からgithubにpushをし、EC2からpullをしたときにエラーが出たのでメモを残します。
以下の記事を参考にして対処しました。
本番環境でpullしたらコンフリクト?解決法3パターン!【Please commit your changes or stash them before you merge】エラーの内容
$ git pull origin master From https://github.com/user-name/app-name * branch master -> FETCH_HEAD Updating e05c05f..050505 error: Your local changes to the following files would be overwritten by merge: Gemfile.lock config/initializers/devise.rb Please commit your changes or stash them before you merge. Aborting私が実践した対処法
terminal$ git fetch origin master $ git reset --hard origin/masterこれで無事にgithubの内容がEC2上に反映されました。
終わりに
今回は少し強引なやり方をしてpullをしましたが、実際の開発現場ではもう少し慎重にgitを扱う必要があるのだと思います。
今後も、gitについて深く勉強していきます。
- 投稿日:2020-03-16T11:25:40+09:00
rspec-railsで使うコマンドを羅列する
- 投稿日:2020-03-16T11:20:30+09:00
gemとbundlerまとめ
- 投稿日:2020-03-16T10:17:32+09:00
テーブルのカラムに変更を加えたいです 【 rails 】
マイグレーションファイルとは
マイグレーションファイルとは、テーブルのカラムを追加したり消したり型を変更したりする役割があるファイル
また、何か、カラムに変更を加える場合、必ずマイグレーションファイルを記述する必要がある
初めに
あーーnameカラム邪魔だなーと、 おもたら削除しましょう?
テーブルのカラム削除方法
①ターミナルに下記のコマンドを記述して実行する
rails generate migration テーブル名 カラム名:データ型
helloland@hellolandnoAir freemarket_sample_65a % rails generate migration users name②マイグレーション ファイルが作られるのでそれに変更の内容を記述して
今回は削除したいので、remove_colum です
③ターミナルでrails db:migrate を実行する
rails db:migraet④カラムが完全に消滅しました
追記
もしエラーが出た場合、あせらずに エラー文を翻訳して解くいていきましょう
また、エラー内容は一行にまとめられているので、そこだけを見ることをお勧めします
大体マイグレーションファイルの記述ミスの場合が大半の為、エラー内容にしたがって作成したマイグレーション ファイルを修正することをお勧めします
- 投稿日:2020-03-16T10:10:34+09:00
Railsのtravel_toについてまとめた
はじめに
日付関係のテストをしていたときに、
travel_to
を使うといいと教えてもらいました。
今回は、travel_to
メソッドについてまとめていきます。travel_toとは
ActiveSupport :: Testing :: TimeHelpers
のメソッドの一つです。変更したい日時を渡すと、
Time.now
、Date.today
、DateTime.now
で返される日時を変更することができます。コード例
travel_to do
とend
で囲まれた部分の中だけ、時間が変更されています。
コメント文のとおりに出力されました。it 'puts date and time' do travel_to Time.zone.local(2020, 03, 16) do pp Date.today # -> Mon, 16 Mar 2020 pp Time.now # -> 2020-03-15 15:00:00 +0000 pp DateTime.now # -> Mon, 16 Mar 2020 00:00:00 +0900 end endSyntaxError
Time.zone.local
に08
または09
を渡すと、Invalid octal digit
でエラーとなります。
そういうときは、下の例のように0
をつけずに渡してあげればOKです。travel_to Time.zone.local(2020, 8, 16) do end参考
ActiveSupport::Testing::TimeHelpers
ActiveSupport :: Testing :: TimeHelpers
には他にもメソッドがあるので参考にしてみてください。
- 投稿日:2020-03-16T00:43:33+09:00
Railsポートフォリオ環境構築備忘メモ(参考にした記事とか)
※こちらは活動報告を兼ねた備忘メモです。参考にした記事はURLを記載していますが、本記事自体にはまとまったTIPS的な情報はないので開いてしまった方はお手数ですがスルーしてください。
Railsポートフォリオ環境構築備忘メモ
繁忙期深夜と休日を使い悶々としながら行っていた環境構築が一旦完了した。
環境構築で行った手順を忘れてしまいそうのでメモしておく。前提条件(バージョン)
Ruby 2.7.0
Rails 5.2.4.1
MySQL 5.7
をDocker、docker-composeを使用して環境構築する。参考にした記事:
①丁寧すぎるDocker-composeによるrails5 + MySQL on Dockerの環境構築(Docker for Mac)
https://qiita.com/azul915/items/5b7063cbc80192343fc0
本当に丁寧。こちらを基本にしてRails.new前の各種ファイルを作成。バージョンと一部内容は変更した。
(自分なりに理解してやりたかったのだが、自分のにわか変更によりハマりまくった…)②仁科俊晴氏ブログの『ローカル開発環境の構築不要!Dockerを利用したRailsアプリ起動手順』
https://nishinatoshiharu.com/docker-rails-server/
こちらも参考にした。かなり分かりやすく入門Dokerや公式ガイドと合わせて理解の助けになったが、複数記事に渡っていてこちらのみを参考にしつつ構築したらハマった。(多分自分のコードが誤っているのだろう)③他の方があげているポートフォリオ
その他気をつけること:
・ymlのインデント周りでエラーを吐きやすい。
・bundle(gem)のバージョン周りでエラーが発生しがちのようだが適当なトラブルシューティングに辿り着けないとハマる。(対策を考えておく。)
・Dockerコンテナやイメージが散らかるので定期的に掃除しておく。ハマりまくるのでブランチを分けて作業すればいいことに途中で気付く…
そして深夜にようやく「Yay! You're on Rails!」画面に…感動。
- 投稿日:2020-03-16T00:16:26+09:00
Ruby, Rails たまに使うけどすぐ忘れるやつ
RailsとかRubyの過去に学んだものを適当に残しておく(最近はRailsもRubyも触ってない・・)
思い出したら随時追加する。rakeタスクをrails consoleから実行する
require 'rake' Rails.application.load_tasks Rake::Task['hoge:huga'].execute # 引数つけて実行 Rake::Task["hoge:huga"].execute({ hogege: 'hugaga' })bundle でバージョン指定してインストール
# bundle installするときはGemfile.lockのバージョンを確認してから実行 bundle _1.16.1_ installrakeタスク内のメソッドはObjectクラス直下に作られちゃう
https://blog.freedom-man.com/rake-definemethod-namespace
namespace配下にメソッド書いていると思っていてもObjectクラス以下に作られるのでバグの原因になるかもね
SQLをrails consoleから実行
sql="SELECT * from hoge);" result=ActiveRecord::Base.connection.select_all(sql).to_hashrspecの書き方で参考になるページ
http://www.betterspecs.org/jp/
ruby引数処理
わかりやすい記事
キーワード引数をhashとして受け取る方法とか
https://qiita.com/metheglin/items/306e81c95f8a5cdea296privateメソッドをrails consoleから呼び出す
# User.find_by(id: 1)は引数 # Hugaはクラス, hoge_private_methodはHugaクラス内のプライベートメソッド Huga.send(:hoge_private_method, User.find_by(id: 1) )CSV書き出し
使い捨てコード書くときによく使う
CSV.open('/tmp/hoge.csv','wb') do |csv| csv << [1,2] endテキスト読み込み
File.foreach("tmp/hoge.txt"){|f| s << f.chomp.to_i}rakeタスクの確認
bundle exec rake -vTrails consoleでexplainを実行
User.where(id: 1).joins(:articles).explainActiveSupportのString拡張(活用形)まとめ
https://qiita.com/hana-da/items/ec9ac3e1c8803f5fa1fc
"Invoice".tableize # => "invoices"メール送信
手元のメール送信確認はmailcacherを使ったことがある
https://qiita.com/pocari/items/de0436c39ffc65647cf0ActionMailer::Base.mail(to: "to@example.com", from: "from@example.jp", subject: "題名", body: "本文").deliver_nowメソッドの定義場所を探す
https://docs.ruby-lang.org/ja/latest/method/Method/i/source_location.html
Hoge.method(:huga).source_locationsqlファイルをrails dbに食わせる
bundle exec rails db < my_db.sql
日付と時刻を扱う
https://qiita.com/prgseek/items/c0fc2ffc8e1736348486
t = Time.parse("2017/04/25 19:23:55"); p t # 2017-04-25 19:23:55 +0900クエリ高速化
わかりやすい, Rails6はあまり知らない
https://texta.pixta.jp/entry/2016/02/10/180244
https://qiita.com/leon-joel/items/f26556c9e56833983856rails consoleの再読み込み
reload!
find_each
わかりやすかった
https://blog.toshimaru.net/rails-find_each/#order%E4%BB%98%E3%81%8D-find_eachスクリプト実行
Rails機能を使いつつ単独のスクリプトを実行する。
bundle exec rails runner hoge.rb 'huga'pry
わかりやすい
https://qiita.com/k0kubun/items/b118e9ccaef8707c4d9f
https://www.slideshare.net/cuzic/pry-repl