- 投稿日:2020-06-03T23:59:12+09:00
Routing Error[No route matches [GET] “/logout”]エラーと格闘した話
前提
-Rails 6.0.3.1
-ruby 2.6.3
railsでアプリを作成中にヘッダーにLogoutのリンクを作成していました。
動作確認で、ボタンを押してみると、
あらまあ....No route matches [GET] “/logout”お怒られました....
頼むから、ログアウトさせてくれ...
旅立たせてくれよ...こうして長いRouting Error[No route matches [GET] “/logout”]エラーとの
戦いが始まるであろうとは、知る由もなかったのである。
やってみたこと
①ルーティングの確認
No route matchesって言ってるし、どうせルーティングミスってるんでしょ!!!
ほんまアホやなワイ。ちゃんとlogout_path使ってるし、HTTP Verb?: POSTになってるやんな(汗)。
ルーティングはあってはるやん
②viewでメソッドの指定の確認
次いこ次。飲み足りんし、二軒目にきました。
<%= link_to “Log out”, logout_path, method: :post, class: “nav-link text-light”%>へいらっしゃい!!!!!!!
と思いきや、お主も合ってはるな。
ちゃんと、postしていますな。③検証ツールで確認
ほいなら、次は個室居酒屋で三軒目や。
HTML上で確認や。a class=“nav-link text-light” rel=“nofollow” data-method=“post” href=“/logout”>Log out</a>fuck the po00ce!!!!!!!!!
マジかいな。まだ飲みたらんな!!!!!!!!!!!
data-method=“post
postさん、ちゃんといるんか............④jQueryがきちんと動いているか確認する
Boys Be Engineer 非エンジニアよ、エンジニアになれ
このイカした記事で、jQueryに問題あるんちゃう?
っていう新たなる誘い。
四軒目に来ました。Rails6でjQueryの導入方法
Rails 6にjQueryとBootstrapを入れる
以上の記事で、rails6での導入方法をかたっぱしから試すロドリゲス。撃沈ロドリゲス.................
ほなもう一軒行こうか......⑤environment.jsの一部の記述を削除
/config/webpack/environment.jsconst { environment } = require('@rails/webpacker') const { VueLoaderPlugin } = require('vue-loader') const vue = require('./loaders/vue') environment.plugins.prepend('VueLoaderPlugin', new VueLoaderPlugin()) environment.loaders.prepend('vue', vue) environment.config.resolve.alias = {'vue$': 'vue/dist/vue.esm.js' } const webpack = require('webpack') environment.plugins.prepend('Provide', new webpack.ProvidePlugin({ $: 'jquery/src/jquery', jQuery: 'jquery/src/jquery' }) ) module.exports = environment今の設定。
それをこうしてこう!!!!(語彙力なし)
/config/webpack/environment.jsconst { environment } = require('@rails/webpacker') #2-7行目をコメントアウト // const { VueLoaderPlugin } = require('vue-loader') // const vue = require('./loaders/vue') // environment.plugins.prepend('VueLoaderPlugin', new VueLoaderPlugin()) // environment.loaders.prepend('vue', vue) // environment.config.resolve.alias = {'vue$': 'vue/dist/vue.esm.js' } #ここまで const webpack = require('webpack') environment.plugins.prepend('Provide', new webpack.ProvidePlugin({ $: 'jquery/src/jquery', jQuery: 'jquery/src/jquery' }) ) module.exports = environmentやっと旅立てる........
vue系のイケイケライブラリが邪魔してたらしい。
環境によっては、コメントアウトしなくても解決するっぽい。**四軒目でわっしょい(jQueryがきちんと動いているか確認する)の記事しかなかったので、わっっしょいできなかった人は、コメントアウトしてみると行けるかもです。
五軒目にして、やっと旅立てる。
わっしょい!!!!!!
- 投稿日:2020-06-03T21:27:16+09:00
【Rails】deviseでのセッションタイムアウト設定
deviseでのセッションタイムアウト設定
目次
- セッションタイムアウトを設定するメリット
- セッションタイムアウトを設定するデメリット
- deviseでのセッションタイムアウト設定
1. セッションタイムアウトを設定するメリット
- セッションの盗用などの不正行為の対策になり、安全にアプリケーションを運用することができる
- 利用ユーザーのステータスを判定することによって、サーバー側の負担を軽減させることができる
2. セッションタイムアウトを設定するデメリット
- 入力フォームなどで、一度中断をし、再開後に入力を行うことができないこと
- ログイン状態が切れる回数が多いと、ユーザーが再度ログインする必要があるので、アプリケーションの使い勝手が悪いと判断されてしまうこと
3. deviseでのセッションタイムアウト設定
3-1. Deviseのセッションタイムアウトを設定
以下の記述を入力しましょう。
(コメントアウトされているので、コメントを解除すればOK)config/initializers/devise.rbconfig.timeout_in = 30.minutes3-2. Userモデルに「timeoutable」を設定
以下の記述を入力しましょう。
app/models/user.rbclass User < ApplicationRecord devise :database_authenticatable, :registerable,...省略...:timeoutable end※ テストを行う際は1分で設定することがおすすめです。
以上でdeviseでのセッションタイムアウト設定になります。
- 投稿日:2020-06-03T21:00:23+09:00
define_methodってどんなmethod?
define_methodってどんなmethod?
gemを読んでいたらdefine_methodなるメソッドが出てきたけど、
よくわからなかったので調べてみた。
直訳するとmethodを定義する。って名前のメソッド。
ますますわからない。。ということで例をみてみます。
ruby.rbNUMBERS = %w(zero one two three four five six seven eight nine) NUMBERS.each_with_index do |word, num| define_method word do |i = nil| i ? num * i : num end end p two #=> 2 p two(2) #=> 4 p nine #=> 9 p nine(3) #=> 27define_methodはmethodを動的に定義できるメソッドです
上記の例でもtwoやnineと言ったメソッドは直接定義したわけではないけれど
メソッドとして使えることができます。
これはdefine_methodによって動的にtwo,nineメソッドが定義されたからです。ruby.rbNUMBERS.each_with_index do |word, num| define_method word do |i = nil| i ? num * i : num end enddefine_methodの引数にwordが渡されています。
これが動的に定義されるメソッド名となります。
wordには["zero","one","two",..."nine"]という配列の要素が入っていきます。
なのでtwo,nineというメソッドが使えました。そしてdefine_methodのブロック部分が動的に定義されるメソッドの処理内容となります。
ruby.rbdefine_method word do |i = nil| i ? num * i : num end内容としてはiが存在するときはi * numを返し、
存在しないときはnumを返すということですね。そしてiは新たに定義されるメソッドの引数に当たっています。
最後に処理結果をもう一度見てみましょう。p two #=> 2 #引数がないのでnumを返す p two(2) #=> 4 #引数があるので 2 * 2 = 4 p nine #=> 9 #引数がないのでnumを返す p nine(3) #=> 27 #引数があるので 9 * 3 = 27define_methodの説明はここまでです。
お役に立てたら幸いです。一人前のエンジニアになるまであと86日
- 投稿日:2020-06-03T19:53:42+09:00
Rails】undefined local variable or method エラーについて【定義しているのに出る!!
- 投稿日:2020-06-03T19:44:10+09:00
非同期でのお気に入り機能の実装
はじめに
お気に入り機能を作成しました。
いいね機能は作ったことがあるので、いいね機能と同じ感じで作成すれば余裕でしょ!と思っていました。
実際に作ってみて、お気に入りにいれることは簡単にできました。
ですがajaxを用いての非同期にしないとお気に入りボタンを押すたびにredirect_toでページ更新されてしまい、ユーザーライクでは無いと思いました。
下のgifが完成品です。
コード&解説
モデルの作成
favoritesモデルを作成します。
class CreateFavorites < ActiveRecord::Migration[5.2] def change create_table :favorites do |t| t.references :user, null: false t.references :product, null: false t.timestamps end end endそしてfavorite.rbを以下のようにしました。
class Favorite < ApplicationRecord belongs_to :user belongs_to :product endそしてuser.rbに
has_many :favorites, dependent: :destroy has_many :favorites, through: :favorites, source: :productproduct.rbに
has_many :favorites, dependent: :destroy has_many :favorites, through: :favorites, source: :userとしました。
これでfavoriteテーブルと言う中間テーブルに、productとuserのidを格納できます。ルーティング
ルーティングを設定します。
resources :products do resources :favorites , only: [:index, :create, :destroy] endお気に入り機能を実装するだけでしたら、createとdestroyだけでOKです。
お気に入りを一覧にしたかったので、indexも追加しています。コントローラー
次にコントローラーです。
class FavoritesController < ApplicationController before_action :set_product, only: [:create, :destroy] def index @favorites = Favorite.where(user_id: current_user.id) # favoriteテーブルからuser_idが現在のユーザーのidの物探し出し、@favoritesに代入しています。 # 後ほどeach文で表示させます。 end def create # お気に入りに追加する記述です。@productはprivateの中に記載されています。 @favorite = Favorite.new( user_id: current_user.id, product_id: @product.id ) @favorite.save end def destroy # お気に入りを削除する記述です。 @favorite = Favorite.find_by( user_id: current_user.id, product_id: @product.id ) @favorite.destroy end private # こちらを記入しないとajaxが上手く起動しませんでした。 def set_product @product = Product.find(params[:product_id]) end endHAML
まずはお気に入りボタンを作りたいところをrenderメソッドを書きます。
%ul#favoriteBtn = render partial: 'favorites/favorite', locals: { product: @product}localsで@productと言う変数を呼び出し元ではproductとして扱えるようにしています。
そしたら呼び出し元であるfavorites/_favorite.html.hamlを作成し、お気に入りボタンのみを記述します。- if Favorite.find_by(user_id: current_user.id, product_id: product.id) = link_to(product_favorite_path(@product, product.id), method: :delete, remote: true) do %li.optionalBtn.already = icon('fa', 'star') お気に入り済み! -else = link_to(product_favorites_path(@product), method: :post, remote: true) do %li.optionalBtn.none = icon('fa', 'star') お気に入りへ!if文で条件分岐してあります。favoriteテーブルに現在のユーザーのidと商品のidが両方一致している物があるかをみています。あれば削除ボタン、無ければ追加ボタンを作成します。link_toの中にはそれぞれremote: trueと言う記述をしています。これがあることでajaxが使えるようになります。
ルートは下記のようになっています。:product_idが必要ですので、先ほどコントローラで定義した@productを記述しています。削除ボタンに関しては商品のidも必要ですので、product.idをカンマでつなげています。product_favorites GET /products/:product_id/favorites(.:format) favorites#index POST /products/:product_id/favorites(.:format) favorites#create product_favorite DELETE /products/:product_id/favorites/:id(.:format) favorites#destroyAjax
次にviews/favoritesの中にcreate.js.erbとdestroy.js.erbを作成します。
中身は全く一緒ですので同じ記載をします。$('#favoriteBtn').html("<%= j(render partial: 'favorites/favorite', locals: { product: @product}) %>");私の場合は#favoriteBtnを非同期通信したいので上記のように記載しています。
ここまできたら非同期でお気に入りボタンが押せるようになっているを思います。お気に入りを一覧表示する。
コントローラで先ほどのindexアクションで@favoritesの中にはお気に入り情報が入ってるはずです。
入っていたらeach文で一個ずつ表示させます。入っていなかったら、お気に入りに追加した商品はありませんと表示させました。- if @favorites.present? %ul - @favorites.each do |favorite| %li = link_to product_path(favorite.product.id) do .item-image = image_tag (favorite.product.images[0].src.url) .item-body .item-name = favorite.product.product_name .item-price = "¥#{favorite.product.price}" - else %h1 お気に入りに追加した商品はありません私が作成しているアプリではトップ画面にお気に入りされた数も表示しています。
下記のようにcountメソッドを使用して数を取ってきています。= Favorite.where(product_id: product.id).count最後に
これでお気に入り登録から一覧表示、お気に入り数までができました。
前回の記事と今回の記事でなかなかajaxについて鍛えられました。
ですが、まだまだひよっこなので勉強していきます。
- 投稿日:2020-06-03T19:11:49+09:00
中学2年が1週間で自分のアイディアをいるかいらないか投票できるTogmarks(トグマークス)作った
アイディアにいるかいらないか投票できるTogmarksというサイトを作りました。5月26日に作り始めて6月2日に公開しました。たった1週間しかかけていませんが前作ったQuaよりもいい出来だと思っています(機能の数は少ない)。今回も前と同じようによかった点と悩んだことを振り返ろうと思います。
紹介
トップページ
素人が個人で1週間で作ったのですごくいいとは言えませんが青色をアクセントカラーにしてシンプルなデザインはそこそこ気に入っています。
投票画面
タイトルと内容は気にしないでください(笑)公開して間もないため投稿がなく開発環境でseedでデータを作るしかなかったんです(泣)
他にもページはありますがどれもtopページと似ていてコメントすることがないので割愛します。
どうして作ったか
自分でアイディアを考えても「これ使われるのかな...人にしられてもいいから他の人の意見が聞きたいな...」と思ったことがよくあります。個人で趣味でやっている人は特にあるとおもいます’。そういうときにこのwebアプリを思いつきました。正直このwebアプリもいると思う人がいるのかわかりませんが投票してくれる人がいるなら自分も使ってみたいです。
今回の良かった点
①サイトマップやデータベース設計をしっかりしてから開発を行った・・・当たり前かもしれませんがQuaのときは一切そういうのをやらなかったので地味にしっかりとやったのは初めてでした。やはりこういうのは重要だなと感じました。
②必要な機能と欲しい機能をわけた・・・最初にそれをまとめておくと次に何をやるべきかがすぐわかるのでスムーズになります。
③cssのコードを少なくできた・・・じつは最も自分的には良かった点です。cssはスマホ用・PC用のデザインと分けるとどうしても長くなりがちですが今回は同じクラスを何回も使うことで最小限似できたと思います。
④技術面で悩んだことが一回もなかった・・・機能とデザインをシンプルにしたからだと思います。悩んだこと
①お金・・・ロゴやイラスト台です。中2が払える訳ありません。最終的にはなしでいくことにしました。ただファビコンはなしでは寂しいのでいつの日か無料のやつ探して設定しようと思います。
②使われるか・・・誰しもが思うことですがこれ使う人いるの...という不安感です。ただこれを乗り切らないとどんなものもできません。最後に
このwebアプリを開発中に最も驚いたのは開発スピードです。これが普通なのかもしれませんが基本機能だけだと1週間で作れてしまうんだなと思いました。
最初にしか触れていませんがこのアプリは1週間で作ったと思えばなかなかなのかな?自分的にはそこそこだと思います。
今回2つ目のアプリですが誰も登録しない...ということだけは避けたいです。みなさんお願いします。
- 投稿日:2020-06-03T19:00:19+09:00
ログイン状態且つ住所テーブルにデータが登録してある場合としてない場合の条件分岐
def new if current_user && Address.find_by(user_id: current_user.id).present? @address = Address.find_by(user_id: current_user.id) render action: :edit else @address = Address.new endif current_user && Address.find_by(user_id: current_user.id).present?2行目 ...presentメソッドはオブジェクトのレシーバーの値が存在すればtrue、存在しなければfalseを返すメソッド。if文などの条件分岐でよく使用するので覚えておきたい。
current_user.idと一致するuser_idが存在すればeditアクションが動く。
ちなみに(renderで同じコントローラーのアクションが動かせるのは本日知りました)6行目...current_user.idと一致するuser_idが存在しなければnewアクションがそのまま動くので新規登録となる。
- 投稿日:2020-06-03T18:26:08+09:00
Rails 5.2/6.0 で MessageEncryptor を使うときは初期化タイミングに気を付けよう
Rails 5.2 から
ActiveSupport::MessageEncryptor
のデフォルト暗号方式がaes-256-cbc
からaes-256-gcm
に変更となった。しかし、期化タイミングによっては意図しない暗号方式を使うことになる場合があるため紹介する。Rails 5.2
以下のバージョンで確認:
- Ruby 2.6.5
- Rails 5.2.4.3
デフォルト
まず
rails console
でデフォルト暗号方式を確認する。irb> encryptor = ActiveSupport::MessageEncryptor.new 'key' => #<ActiveSupport::MessageEncryptor:0x0000561c2eae8940 @secret="key", @sign_secret=nil, @cipher="aes-256-gcm", @aead_mode=true, @verifier=ActiveSupport::MessageEncryptor::NullVerifier, @serializer=Marshal, @options={}, @rotations=[]> irb> encryptor.instance_variable_get '@cipher' => "aes-256-gcm"確かに
aes-256-gcm
であることがわかる。実例
実際のアプリケーションでは、なんらかのモデルに持たせておいて利用することもあるだろう。
app/models/some_model.rbclass SomeModel < ApplicationRecord class << self attr_reader :encryptor def set_key(key) @encryptor = ActiveSupport::MessageEncryptor.new key end end set_key 'x' * 32 endこれも同じように確認してみる。
irb> SomeModel.encryptor.instance_variable_get '@cipher' => "aes-256-gcm"問題なさそうに見える。
問題例
ところが、
MessageEncryptor
の初期化タイミングが早すぎると、異なる暗号方式になってしまう。例えばafter_initialize
コールバック内でSomeModel
定数が参照されていると、そのタイミングでオートロードされ、MessageEncryptor
が生成されることとなる。config/application.rbclass Application < Rails::Application config.load_defaults 5.2 config.after_initialize do SomeModel end endirb> SomeModel.encryptor.instance_variable_get '@cipher' => "aes-256-cbc"
aes-256-gcm
ではなくaes-256-cbc
となってしまった。原因
ことの問題は
Rails.application.config.active_support.use_authenticated_message_encryption
の設定反映のタイミングにある。この設定値は過去バージョンとの互換性のために設けられており、false
に設定することでデフォルト暗号方式をaes-256-cbc
に戻すことができる。本設定値は Rails 5.2 としてはデフォルトtrue
ではあるが、この設定値がconfig.after_initialize
実行時点ではまだ反映されていないようなのだ。従ってこのタイミングで初期化してしまうと、MessageEncryptor
自身のデフォルトであるaes-256-cbc
となってしまう。該当コードはこのあたりである。
解決例
初期化が早すぎるのが問題なので、実際の利用タイミングまで遅らせることが考えられる。
app/models/some_model2.rbclass SomeModel2 < ApplicationRecord class << self def set_key(key) @key = key end def encryptor @encryptor ||= ActiveSupport::MessageEncryptor.new @key end end set_key 'x' * 32 endconfig/application.rbconfig.after_initialize do SomeModel2 endこれでほとんどの場合
aes-256-gcm
が利用できる。irb> SomeModel2.encryptor.instance_variable_get '@cipher' => "aes-256-gcm"ただし、
MessageEncryptor
を利用したいタイミング自体がuse_authenticated_message_encryption
の設定反映前である場合は、これでも解決とはならない。そのときはMessageEncryptor.new
にcipher:
オプションを明示するのが良いだろう。Rails 6
以下のバージョンで改めて調査したが、同じ状況になるようだ。
- Ruby 2.7.1p83
- Rails 6.0.3.1
5.2 と少し事情が違うのは、デフォルトのオートローダーが Zeitwerk となり
config/initializers/*.rb
で各モデルをオートロードするのが非推奨となった点だ。このためconfig/initializers/*.rb
でうっかりモデルを参照してしまった場合は、警告メッセージにて検出が可能となっている。しかしながら本記事での例のように、config.after_initialize
では警告はないようだ。Rails では各ファイルは必要に応じてロードされるが、その順番はときに分かりづらいこともある。ロード順によって問題が発生することもあるので気を付けよう。
- 投稿日:2020-06-03T17:45:47+09:00
【git/基本編】これだけは押さえてほしいgitの仕組み&コマンド完全攻略版
今回やること
gitコマンドを使えることは個人開発でもチーム開発でも必須です
特にチーム開発ではgitを使う機会が非常に多くなります
かなり基本的な仕組みとコマンドのみなので実際に使って身につけていただけたらと思います
git(基本編)
gitの仕組み
①ワークツリー
下記コマンドでワークツリーでの変更をステージに記録していきます
$ git add②ステージ
下記コマンドでステージからローカルリポジトリにコミット(記録を保存)することができます
$ git commit$ git commit -m "" # メッセージ付きで記録(変更)を保存$ git commit -v # 変更内容を確認してからcommitが可能③ローカルリポジトリ
下記コマンドでリモートリポジトリにプッシュ(送る)ことができます
$ git push リモート名 ブランチ名④リモートリポジトリ
リモートリポジトリはGitHubなどのアプリケーションなどのファイル・ディレクトリの履歴を管理するネット上の場所のことです
リモートリポジトリにファイルなどをアップロードすることでバージョンごとに履歴を管理することができるため、開発において不本意な変更があった際に簡単に戻したいバージョンに戻すことができます
もっと詳しい仕組みを知ってちゃんとgitを使いこなしたい方は下の記事をご覧ください
ブランチとは
ブランチとは現在のコミットを指しているただのポインタのことです
それでは以下のgitコマンドでブランチを新規追加していきましょう
$ git branch ブランチ名$ git branch feature # 作成したブランチに移動$ git checkout feature上の2つのコマンドを同時に行うコマンドが下のコマンドです
$ git checkout -b featureもっと詳しくブランチについて知ってから他のgitコマンドを身につけたい方は下の記事をご覧ください
開発の流れ
1. クローンを作る(コピーを作成する)
リモートリポジトリ(GitHub等)のファイルがワークツリーとローカルリポジトリ(.git directoryが)にコピーされる
$ git clone <repository url>2. ブランチを作る
$ git checkout -b feature3. プッシュする
$ git push リモート名 ブランチ名4. 修正する
プロジェクトに変更を加える
5. 完了後にコミットする
$ git add .コミットしていきます
$ git commit -m "First commit"6. プッシュする
$ git push7. Pull requestを送る
GitHub上でプルリクエストを送ります
以上がgitでの開発の流れですが説明はかなり省略しています
もっと詳しく知って実際の開発に役立てたい方は下の記事をご覧ください
新規プロジェクトをGitHubで扱う
①git init
$ git initGit に必要なファイル(.git)がダウンロードされます
②リモートリポジトリ(github)を新規で登録する
GitHubをブラウザで開き新規リポジトリを作成してください
その後下のコマンドを打ち込みます
$ git remote add origin githubのURL③プッシュする
$ git push -u origin masterかなり端折って紹介したのでもっとわかりやすい説明は下の記事からご覧ください
開発で役立つコマンド
リモートから情報を取得する
リモートリポジトリから情報を取得するには以下の2種類の方法があります
- フェッチ(fetch)
- プル(pull)
①フェッチ
以下のgitコマンドでリモートリポジトリから情報を取得できます
$ git fetch リモート名専用に作成されたブランチのワークツリー には以下のgitコマンドを使って反映していきます
$ git merge origin/master②プル
pullコマンドはこのコマンド1つで以下2つの役割を持ちます
$ git fetch origin master $ git merge origin/master実際のプルコマンドは以下です
$ git pull リモート名 ブランチ名簡単なフェッチとプルの使い方だけだとわかりにくいと思うので下の記事もご覧ください
リモート名の変更/削除
リモート名の変更
$ git remote rename 旧リモート名 新リモート名 $ git remote rename sample_app test_appリモートの削除
$ git remote rm リモート名 $ git remote rm test_appもっと詳しく知りたい方は下の記事が役立つと思います
rebaseコマンドの使い方
*基本的な使い方
$ git rebase -I HEAD~数修正したいコミットをpickからeditに変更して保存/ファイルを閉じます(コミット削除:pick~文を削除、コミット並び順変更:pick~文を並び替える)
$ git commit --amendエディタが立ち上がるのでコミットメッセージを変更してください
$ git rebase -continue*ブランチの変更を別ブランチに取り込みたい場合
$ git rebase master $ git merge feature $ git rebase -I HEAD~数修正したいコミットをpickからsquashに変更して保存/ファイルを閉じます
*コミットを分割したい場合
$ git rebase -I HEAD~数分割したいコミットをpickからeditに変更して保存/ファイルを閉じます
$ git reset HEAD^別々にgit addでステージに上げてgit commitでコミットします
$ git add . $ git commit -m "First commit" $ git add . $ git commit -m "Second commit" $ git rebase —continue以上がrebaseの使い方となりますがこれだけだとイメージが湧かないと思います
rebaseは開発において非常に重要な箇所なので是非詳しい説明は下の記事でご覧ください
ここまででgitの基本を押さえられると思います
まだまだgitコマンドはありますが、まずは今回紹介した基礎を身につけて実際に使ってみてください
開発をする際に必ず役立つと思います
今回の元記事は下の記事になります
- 投稿日:2020-06-03T17:45:47+09:00
【git/基本編】これだけわかれば100%オッケーなgitの仕組み&コマンド完全攻略版
今回やること
gitコマンドを使えることは個人開発でもチーム開発でも必須です
特にチーム開発ではgitを使う機会が非常に多くなります
かなり基本的な仕組みとコマンドのみなので実際に使って身につけていただけたらと思います
git(基本編)
gitの仕組み
①ワークツリー
下記コマンドでワークツリーでの変更をステージに記録していきます
$ git add②ステージ
下記コマンドでステージからローカルリポジトリにコミット(記録を保存)することができます
$ git commit$ git commit -m "" # メッセージ付きで記録(変更)を保存$ git commit -v # 変更内容を確認してからcommitが可能③ローカルリポジトリ
下記コマンドでリモートリポジトリにプッシュ(送る)ことができます
$ git push リモート名 ブランチ名④リモートリポジトリ
リモートリポジトリはGitHubなどのアプリケーションなどのファイル・ディレクトリの履歴を管理するネット上の場所のことです
リモートリポジトリにファイルなどをアップロードすることでバージョンごとに履歴を管理することができるため、開発において不本意な変更があった際に簡単に戻したいバージョンに戻すことができます
もっと詳しい仕組みを知ってちゃんとgitを使いこなしたい方は下の記事をご覧ください
ブランチとは
ブランチとは現在のコミットを指しているただのポインタのことです
それでは以下のgitコマンドでブランチを新規追加していきましょう
$ git branch ブランチ名$ git branch feature # 作成したブランチに移動$ git checkout feature上の2つのコマンドを同時に行うコマンドが下のコマンドです
$ git checkout -b featureもっと詳しくブランチについて知ってから他のgitコマンドを身につけたい方は下の記事をご覧ください
開発の流れ
1. クローンを作る(コピーを作成する)
リモートリポジトリ(GitHub等)のファイルがワークツリーとローカルリポジトリ(.git directoryが)にコピーされる
$ git clone <repository url>2. ブランチを作る
$ git checkout -b feature3. プッシュする
$ git push リモート名 ブランチ名4. 修正する
プロジェクトに変更を加える
5. 完了後にコミットする
$ git add .コミットしていきます
$ git commit -m "First commit"6. プッシュする
$ git push7. Pull requestを送る
GitHub上でプルリクエストを送ります
以上がgitでの開発の流れですが説明はかなり省略しています
もっと詳しく知って実際の開発に役立てたい方は下の記事をご覧ください
新規プロジェクトをGitHubで扱う
①git init
$ git initGit に必要なファイル(.git)がダウンロードされます
②リモートリポジトリ(github)を新規で登録する
GitHubをブラウザで開き新規リポジトリを作成してください
その後下のコマンドを打ち込みます
$ git remote add origin githubのURL③プッシュする
$ git push -u origin masterかなり端折って紹介したのでもっとわかりやすい説明は下の記事からご覧ください
開発で役立つコマンド
リモートから情報を取得する
リモートリポジトリから情報を取得するには以下の2種類の方法があります
- フェッチ(fetch)
- プル(pull)
①フェッチ
以下のgitコマンドでリモートリポジトリから情報を取得できます
$ git fetch リモート名専用に作成されたブランチのワークツリー には以下のgitコマンドを使って反映していきます
$ git merge origin/master②プル
pullコマンドはこのコマンド1つで以下2つの役割を持ちます
$ git fetch origin master $ git merge origin/master実際のプルコマンドは以下です
$ git pull リモート名 ブランチ名簡単なフェッチとプルの使い方だけだとわかりにくいと思うので下の記事もご覧ください
リモート名の変更/削除
リモート名の変更
$ git remote rename 旧リモート名 新リモート名 $ git remote rename sample_app test_appリモートの削除
$ git remote rm リモート名 $ git remote rm test_appもっと詳しく知りたい方は下の記事が役立つと思います
rebaseコマンドの使い方
*基本的な使い方
$ git rebase -I HEAD~数修正したいコミットをpickからeditに変更して保存/ファイルを閉じます(コミット削除:pick~文を削除、コミット並び順変更:pick~文を並び替える)
$ git commit --amendエディタが立ち上がるのでコミットメッセージを変更してください
$ git rebase -continue*ブランチの変更を別ブランチに取り込みたい場合
$ git rebase master $ git merge feature $ git rebase -I HEAD~数修正したいコミットをpickからsquashに変更して保存/ファイルを閉じます
*コミットを分割したい場合
$ git rebase -I HEAD~数分割したいコミットをpickからeditに変更して保存/ファイルを閉じます
$ git reset HEAD^別々にgit addでステージに上げてgit commitでコミットします
$ git add . $ git commit -m "First commit" $ git add . $ git commit -m "Second commit" $ git rebase —continue以上がrebaseの使い方となりますがこれだけだとイメージが湧かないと思います
rebaseは開発において非常に重要な箇所なので是非詳しい説明は下の記事でご覧ください
ここまででgitの基本を押さえられると思います
まだまだgitコマンドはありますが、まずは今回紹介した基礎を身につけて実際に使ってみてください
開発をする際に必ず役立つと思います
今回の元記事は下の記事になります
- 投稿日:2020-06-03T16:39:11+09:00
railsでsnsアプリ開発
rails勉強のためにtwitterのようなsnsアプリを作成する。
あくまで個人的なメモみたいなので,めちゃくちゃ汚いです.環境構築
rails ploject作成(失敗)
作成ディレクトリ内で
$ rails new sns-app
→databaseをpostgresqlにしなければならないため、
rm -rf sns-app
でアプリケーションごと削除postgresql
入っていることを確認
$ psql --version
psql (PostgreSQL) 10.10 (Ubuntu 10.10-0ubuntu0.18.04.1)postgres始動
sudo /etc/init.d/postgresql start
sudo su -
sudo su postgres
でpostgresアカウントに切り替えpostgresアカウントで
$psql
でpostgresqlを動かせる状態(DB内)に
/du
でroleの一覧
create role "name" login createdb password "passwd";
でcreate DBが出来るroleを作成
ctrl + d
または/q
でDB外へ
psql -U ryosuke postgres
でuserを指定してDB内へ
sudo service postgresql stop
でpostgresqlを停止改めてrails project作成
参考2
rails new sns-app -d postgresql
でDBにpostgresqlを指定して作成config/database.ymlのdefaultに以下の3行を追加
username: <username> # 設定したPostgreSQL Accountと同一のもの
password: <password> # 設定したPostgreSQL Accountと同一のもの
host: localhostgit接続
git config user.name
で設定確認
git config user.email作成したディレクトリ上で
git init
git add -A
git commit -m "first commit"
git remote add origin <gitのurl>
git push -u origin master実際の開発
基本的にrails tutorialを参考に進めていく。
また、rails tutorial通りで動かなかったものをメモしていく。
6章
データをセーブし忘れたので、データがずれてしまったので、
rails db:migrate:resest
でデータベースをリセットする。
rails bd:reset
でもいいらしいが、その後migrateファイルを実行する必要がある。8章
dropdownさせたいが、railstutorial通りにしてもdoropdownできない。
調べてみたところ、_header.html.erbの最後に_header.html.erb<script src="//ajax.googleapis.com/ajax/libs/jquery/1.11.0/jquery.min.js"></script> <script src="//netdna.bootstrapcdn.com/bootstrap/3.1.1/js/bootstrap.min.js"></script> <script> $('.dropdown-toggle').dropdown() </script>を追加したら、dropdownできるようになった。
11章、12章は飛ばす
アカウントの有効化、パスワードの再設定はメールアドレスが必要になるためとりあえずはやらないで13章へいく。
一旦落ち着いた後やるかもしれない。13章
大体のpostは実装
写真の投稿はいったん飛ばすrailstutorial 終了
snsアプリの大元となるrails turorial のアプリケーションの開発がおわった。
ここから先は追加機能である
・投稿に対するコメント
・投稿に対するいいね
を実装していく。いいね(Like)機能
イメージ
・投稿に「Like」マークを追加する。
・いいねしてないときは「Like」、したら「Liking」になる
・自分がいいねしたやつだけを表示する実装はユーザーのfollowと似たようなものになると思う。
上記の参考文献1でいいねの実装はできた。
次は、自分がいいねしているポストを表示させるページをつくる。ルーティングなど、基本的なところはフォロワー表示と同じ。
ユーザーがいいねしているポストは次の参考2のように、関連付けをすることで簡単に取れる。user.rbhas_many :like_post, through: :likes, source: :post最後に、いいねをしたときのステータスの数字が変わるようにajax化する。
ここも、基本的にはフォロワーの時と同じようにしていく。
likes/create.js.erb$("#post-<%= @post.id %> .like").html("<%= escape_javascript(render "likes/like", post: @post) %>"); $("#iines").html('<%= current_user.likes.count %>');likes/destroy.js.erb$("#post-<%= @post.id %> .like").html("<%= escape_javascript(render "likes/like", post: @post) %>"); $("#iines").html('<%= current_user.likes.count %>');以上のようにすればいい。
初めはcurrent_user
を@user
にしていてはまった。
あくまで変えるのは今ログインしている人のいいね数であって、投稿したひとのいいね数を変えるわけではないということ。しかし、
current_user
にしたことで、他の人のページでお気に入りするとその人のいいね数が、ログインしている人のいいね数に変わってしまう。
とりあえずの対処として、以下のようにshared/_stat.html.erb<% if current_user?(@user) %> <a href="<%= iines_user_path(@user) %>"> <strong id="iines" class="stat"> <%= @user.likes.count %> </strong> iines </a> <% end %>ログインしているひと以外のページでは、その人のいいね数を表示させないことにした。
しかし、これでは、その人がいいねしているものがわからないので、今後違う案を考える。追記:
色々やってみた結果、以下のようにshared/_stat.html.erb<a href="<%= iines_user_path(@user) %>"> <strong <%if current_user?(@user)%> id = "iines" <%end%> class="stat"> <%= @user.likes.count %> </strong> iines </a>
current_user
の時のみidを通すことで、ログインしている人のいいね数だけ変わるようにした。コメント機能
参考3と基本的にやりたいことが同じなのでそこをみて進めていく。
違うところは随時メモしていく。参考3は新たにコメントページを作るものだった。
今回やりたいのはタイムラインにコメント機能をのせたいので、新たに思考錯誤しながらやっていこうと思う。とりあえず完成した。
db/migrate/[timestamp]_create_comments.rbclass CreateComments < ActiveRecord::Migration[5.2] def change create_table :comments do |t| t.string :content t.integer :user_id t.integer :post_id t.timestamps end add_index :comments, :user_id add_index :comments, :post_id add_index :comments, [:user_id, :post_id] end endmodels/comment.rbclass Comment < ApplicationRecord belongs_to :user belongs_to :post validates :user_id, presence: true validates :post_id, presence: true validates :content, presence: true, length: {maximum: 255} endcontrollers/comments_controller.rbclass CommentsController < ApplicationController before_action :logged_in_user before_action :correct_user, only: :destroy def create @comment = current_user.comments.build(content: params[:comment][:content], post_id:params[:post_id] ) if @comment.save flash[:success] = 'comment create.' redirect_to root_url else redirect_to root_url #render 'static_pages/home' end end def destroy @comment.destroy flash[:success] = "Post deleted" redirect_to request.referrer || root_url end private def correct_user @comment = current_user.comments.find_by(id: params[:id]) redirect_to root_url if @comment.nil? end endconfig/routes.rbresources :comments, only: [:create, :destroy]views/comments/_comment.html.erb<% if post.comments.any? %> <ol class="comments"> <% post.comments.each do |comment| %> <li id="comment-<%= comment.id %>"> <%#= link_to gravatar_for(comment.user, size:50),comment.user %> <span class="postuser">from <%= link_to "@#{comment.user.name}", comment.user %></span> <span class="content"><%= comment.content %></span> <span class="timestamp"> Commented <%= time_ago_in_words(comment.created_at) %> ago. <% if current_user?(comment.user) %> <%= link_to "delete", comment, method: :delete, data: { confirm: "You sure?" } %> <% end %> </span> </li> <% end %> </ol> <% end %> <%= render 'comments/comment_form', post: post%>view/comments/_comment_form.html.erb<% if !current_user?(post.user) %> <%= form_for(post.comments.build) do |f| %> <div><%= hidden_field_tag :post_id, post.id %></div> <%#= render 'shared/error_messages', object: f.object %> <table> <tr> <td> <div class="comment_text_field"> <%= f.text_field :content, placeholder: "Compose new comment..." %> </div> </td> <td> <%= f.submit "Comment", class: "btn btn-success btn-sm btn-block" %> </td> </tr> </table> <% end %> <% end %>view/posts/_post.html.erb<li id="post-<%= post.id %>"> <%= link_to gravatar_for(post.user, size:50),post.user %> <span class="user"><%= link_to post.user.name, post.user %></span> <span class="content"><%= post.content %></span> <span class="timestamp"> Posted <%= time_ago_in_words(post.created_at) %> ago. <% if current_user?(post.user) %> <%= link_to "delete", post, method: :delete, data: { confirm: "You sure?" } %> <% end %> </span> <%= render "likes/like", post: post %> <%= render 'comments/comment', post: post %> </li>基本的にポストを実装したとき同じ感じだった。
終了!
- 投稿日:2020-06-03T16:02:51+09:00
Rails tutorialでMySQLを使う方法
rails tutorialも2週目に入りsqliteでは無く、今後を考えmysqlを使いたいと考えた。
rails new アプリケーション名 --database=mysql
上記を使用することでmysqlが使用できるとのことだがエラーが発生。
下記を実行しろと言われるのでそのまま従う。
gem install mysql2 -v '0.5.3' --source 'https://rubygems.org/'
rails sを使用するとmysqlにエラーがあるよと言われる。bundle installすると同じエラーが発生してしまう。結論から言うと、下記コマンドを順に実施することで解決した。
sudo apt-get install libmariadb-dev
sudo apt-get install libmysqlclient-dev
sudo yum install mysql-devel'
gem install mysql2 -v '0.5.3' --source 'https://rubygems.org/'新しいパッケージを入れるためには、その元となる「-dev」なんとかdevというものを事前にインストールしておく必要があるらしい。このgem install するときの元となるデータがなかったためエラーになったみたいだ。
- 投稿日:2020-06-03T15:24:02+09:00
Rails Herokuデプロイ手順
プログラミング初学者のため訂正がありましたらご指摘ください。
gitをインストールしている前提です。自身の環境
- Ruby 2.5.1
- Ruby on Rails 5.2.4.1
- MySQL (gem 'mysql2', '>= 0.4.4', '< 0.6.0')
デプロイの流れ
- The Heroku CLIの設定
- Herokuにログイン
- Herokuにデプロイ
Herokuとは
HerokuとはWebアプリケーションを簡単に全世界に公開できるクラウドプラットフォームです。
参考)HEROKU とは
以下のURLからHerokuのユーザー登録を行います。ユーザー登録は無料です。
1. The Heroku CLIの設定
The Heroku CLIをインストールすることで、Herokuのコマンドが使えるようになります。
下記のリンクからOSを指定してダウンロードしてインストールを完了させてください。
https://devcenter.heroku.com/articles/heroku-cli
2. Herokuにログイン
The Heroku CLIをインストールしたので、ターミナル上でHerokuのコマンドが使えるようになりました。
早速ターミナルからHerokuにログインしましょう。
Herokuへアップロードしたいアプリのディレクトリへ移動し、「heroku loginコマンド」を実行してください。
loginコマンド実行後、herokuに登録したメールアドレスとパスワードの入力が必要です。
$ cd app # appの部分を自分の作ったアプリ名にします $ heroku login # herokuにログインする Enter your Heroku credentials: Email:メールアドレスとパスワードの入力が完了すると以下のように表示されます。
Logged in as 入力したメールアドレス3. Herokuにデプロイ
HerokuではPostgreSQLデータベースを使います。
なので、PostgreSQLをインストールしていきます。
以下のコマンドをターミナルで実行します。(既にインストールされている方はインストールしなくて大丈夫です。)
$ brew install postgresqlインストールが完了したら、本番 (production) 環境にpg gemをインストールしてRailsがPostgreSQLと通信できるようにします。
以下のコードをGemfileの最下部に追加してください。
Gemfile.group :production do gem 'pg' endpg gemは本番用のgemでローカル環境にはインストールしないようにします。その場合、bundle installに--without productionを追加します。このフラグを追加することで、pg gemはローカル環境には反映されないようになります。それでは以下のコマンドを実行します。
$ bundle install --without productionbundle installの本番環境用
次に「heroku create アプリ名」コマンドでheroku上にアプリケーションを作成します。 以下のコマンドを実行します。
$ heroku create上記のようにアプリ名を入力しないと自動で名前をつけてくれます。
一度登録した名前は使えないので注意してください上記のコマンドを実行すると、以下のような結果が表示されます。
Creating app... done, ⬢ app(アプリ名) https://app(アプリ名).herokuapp.com/ | https://git.heroku.com/app(アプリ名).githttps://~~.herokuapp.com/が上記のコマンドで作成されたサブドメインです。 この時点でブラウザに表示可能ですが、今はまだ何もありません。デプロイしてWebページを表示させましょう。
RailsアプリケーションをHerokuにデプロイするには、まずGitを使ってHerokuにリポジトリをプッシュします。
$ git add . $ git commit -m "initial commit" $ git push heroku master上手く行くと、下記のようにremote: Verifying deploy... done.と表示されます。
. . . remote: Verifying deploy... done. To https://git.heroku.com/app(アプリ名).git * [new branch] master -> master次に以下コマンドでmigrationを実行します。ローカル環境で行なっていたrails db:migrateのコマンドを本番環境でも行うというイメージです。
$ heroku run rails db:migrate上記のコマンドを実行したら、以下のコマンドを実行してWebページを表示させましょう。
$ heroku open以上です。
参考記事
https://qiita.com/kazukimatsumoto/items/a0daa7281a3948701c39
https://qiita.com/NaokiIshimura/items/eee473675d624a17310f
- 投稿日:2020-06-03T14:49:31+09:00
【質問用メモ】paramsが全く理解できていない【Rails】
- 投稿日:2020-06-03T14:00:44+09:00
[Rails]フォームのすべての値をワンクリックで初期化する(helperメソッド定義+JavaScript)
はじめに
様々な検索条件を付けられる検索フォームを実装している中で、検索条件をワンクリックでリセットできる方法がないかと試行錯誤しました。
結果、下記の方法で実装できたのでまとめます。
環境
- Ruby2.5.1
- Rails5.2.4
手順
概要を簡単に説明すると、
1. ヘルパーメソッドにリセットボタンタグを生成するメソッドを定義
2. ビューでそれを呼び出す
3. チェックボックスをjsでクリアする処理を書く
という3本でお送りする感じです1. ヘルパーメソッドの定義
どのファイルでもいいですが、今回は
helpers/application.rb
に定義します。helpers/application.rbmodule ApplicationHelper def reset_tag(value = "Reset form", options = {}) options = options.stringify_keys tag :input, { type: "reset", value: value }.update(options) end end2. ビューファイルで呼び出し
search.html.haml%div = reset_tag 'クリア', id: 'js_clear_btn' %div = f.submit '完了'本来Railsに
reset_tag
はありませんが、ヘルパーメソッドで定義したので、この書き方で呼び出せます。3. チェックボックスをJavaScriptでクリアする記述
私の場合は、リセットボタンだとチェックボックスをクリア(チェックを外す)ことができなかったので、そこはJavaScript書きました。
コードは環境に大きく依存してしまうので、割愛します。
結果
こんな感じで、text_fieldもnumber_fieldも、selectもcheckboxもすべて初期化するボタンを作成できました!参考
- 投稿日:2020-06-03T13:34:50+09:00
macにrailsがインストールできない
この記事について
プログラミングの勉強をしています。
勉強の過程で得た知識を、忘れないようまとめておくのと共に、誰かの助けになればと思います。「rails -v」が上手くいかない!
(base) hoge@MacBook-Pro ~ % rails -v Rails is not currently installed on this system. To get the latest version, simply type: $ sudo gem install rails You can then rerun your "rails" command.調べた通りにrailsをインストールしたのに、rails -vを何度実行してもこのエラーが出てしまいます。
対処法
rbenv rehashこのコマンドを実行し、再度rails -vを実行すると
(base) hoge@MacBook-Pro ~ % rails -v Rails 6.0.3.1上手くいきました!!
参考
https://qiita.com/amuyikam/items/313bc89c1de320a4257e
https://github.com/railsgirls-jp/coach.info/issues/32
- 投稿日:2020-06-03T12:40:18+09:00
【Rails】Geocoding APIを用いて高精度で緯度経度を算出し、Google Mapに表示する方法
目標
ユーザーが登録した住所をマップの中心に表示し、マーカーを立てる。
開発環境
・Ruby: 2.5.7
・Rails: 5.2.4
・Vagrant: 2.2.7
・VirtualBox: 6.1
・OS: macOS Catalina前提
下記実装済み。
・Slim導入
・ログイン機能実装
・Google Map表示
gem 'geocoder'
だけでは精度が低い(番地指定が出来ない地域がある)為、
Geocoding API
を使用して高精度で住所から緯度経度を特定出来る様に実装していきます。
Geocoding API
有効化1.下記リンクにアクセス
2. 「APIの概要に移動」をクリック
3.「ライブラリ」をクリック
4.検索フォームに「geo」と入力し、「Geocoding API」をクリック
5.「有効にする」をクリック
6.赤枠で囲われている箇所をクリック
7.プルダウンメニューが表示されるので、「全てのGoogle Maps API」をクリック
8.「認証情報」をクリック
9.「APIキーの名前」をクリック
10.認証情報の設定をする
①APIの制限
キーを制限
を選択し、プルダウンメニューからGeocoding API
を選択する。②
Maps JavaScript API
と、Geocoding API
が選択されている事を確認して、保存
をクリック11.APIが2個になっているかを確認
APIを追加した事でAPIキーが変更されるという事は無いので、これで完了。
実装
1.Gemを導入
Gemfilegem 'gon' gem 'geocoder'
gem 'gon'
➡︎ コントローラーで定義したインスタンス変数をビューのJavaScript内で使用出来る様にする。
gem 'geocoder'
➡︎ 住所から緯度経度を算出する。ターミナル$ bundle2.
geocorder
の設定ファイルを作成し、編集ターミナル$ touch config/initializers/geocoder.rbgeocoder.rb# 追記 Geocoder.configure( lookup: :google, api_key: ENV['GOOGLE_MAP_API'] )これで
Geocoding API
を使用する事ができ、緯度経度の算出が高精度で行えます。3.カラムを追加
ターミナル$ rails g migration AddColumnsToUsers address:string latitude:float longitude:floatadd_columns_to_users.rbclass AddColumnsToUsers < ActiveRecord::Migration[5.2] def change add_column :users, :address, :string add_column :users, :latitude, :float add_column :users, :longitude, :float end endターミナル$ rails db:migrate4.モデルを編集
user.rb# 追記 geocoded_by :address after_validation :geocode
geocoded_by :address
➡︎ addressカラムを基準に緯度経度を算出する。
after_validation :geocode
➡︎ 住所変更時に緯度経度も変更する。5.コントローラーを編集
①
application_controller.rb
を編集ストロングパラメーターに「address」を追加します。
application_controller.rbdef configure_permitted_parameters devise_parameter_sanitizer.permit(:sign_up, keys: [:email, :name, :address]) end②
users_controller.rb
を編集users_controller.rbdef show @user = User.find(params[:id]) gon.user = @user # 追記 end6.ビューを編集
①
application.html.slim
を編集
gon
を読み込みます。
CSSとJavaScriptより先に読み込んでいる事に注意して下さい。application.html.slimdoctype html html head title | Bookers2 = csrf_meta_tags = csp_meta_tag = include_gon # 追記 = stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload' = javascript_include_tag 'application', 'data-turbolinks-track': 'reload'②新規会員登録画面に住所入力フォームを追加
resistrations/new.html.slim= f.label :address, '住所' br = f.text_field :address, class: 'form-control' br③マップを編集
users/show.html.erb#map style='height: 500px; width: 500px;' - google_api = "https://maps.googleapis.com/maps/api/js?key=#{ ENV['GOOGLE_MAP_API'] }&callback=initMap".html_safe script{ async src=google_api } javascript: let map; function initMap() { geocoder = new google.maps.Geocoder() map = new google.maps.Map(document.getElementById('map'), { // コントローラーで定義した変数から緯度経度を呼び出し、マップの中心に表示 center: { lat: gon.user.latitude, lng: gon.user.longitude }, zoom: 12, }); marker = new google.maps.Marker({ // コントローラーで定義した変数から緯度経度を呼び出し、マーカーを立てる position: { lat: gon.user.latitude, lng: gon.user.longitude }, map: map }); }注意
turbolinks
をオフにしないと地図が切り替わらないので、必ずオフにしましょう。
「turbolinksをオフにする方法」につきましては後日記事にしたいと思います。
- 投稿日:2020-06-03T09:18:29+09:00
Rails と Vue の共存
Rails と Vue の共存をしたい。
できれば以前のコードを活かしたい。
いきなりSPAにするにはサンクコストが大きくて、踏ん切りがつかない。参考
2018年くらいに書かれたものが多い。Railsの遺産を残しながらVueの単一コンポーントの利点を使いたい、しかしSPAには振り切りきれない。
- Vue.jsとRailsの最適な融合を考える
- 実際のサービスをRails+Vue.js(Single File Components)を用いてSPAへリファクタリングした話
- SPAじゃないVue.js〜Railsとともに〜
webpack
- RailsでVue.jsのSFC(単一ファイルコンポーネント)を使うためにWebpackを入れてみた
- Vue.jsのコンポーネント化の方法まとめ(rails+webpacker+vue.js)
- Webpackerを導入してから外すまでをふりかえる
- Rails に Webpack と Vue を導入しました!
Sprockets
未検討
検討中
- Webpacker を使わずに webpack
- Sprockets 検討中(よくわかっていない)
- Vue をRailsとは別でBuildしてマウントする方式が良さそう
- 投稿日:2020-06-03T01:26:22+09:00
AWSへのRailsアプリのデプロイ その2
はじめに
今回は以下の記事の続きです。アプリのデプロイまで行っていきます。
AWSへのRailsアプリのデプロイ その1
データベースのインストール
以下のコマンドでバージョン5.6をインストールします。
バージョンについては、各々の環境ごとに適当なものを選択してください。sudo yum -y install mysql56-server mysql56-devel mysql56さっそくmysqlを立ち上げます。
sudo service mysqld startmysqlのrootユーザーのパスワードを設定します。
sudo /usr/libexec/mysql56/mysqladmin -u root password 'ここにパスワードを入力'パスワードが設定できたか確認します。
mysql -u root -pパスワードの入力を促されるため、先ほど設定したパスワードを入力します。
Enter password:mysqlへのログインが正常終了すれば「mysql>」が表示されSQL文を実行できるようになります。
Welcome to the MySQL monitor. Commands end with ; or \g. Your MySQL connection id is 3 Server version: 5.6.47 MySQL Community Server (GPL) Copyright (c) 2000, 2020, Oracle and/or its affiliates. All rights reserved. Oracle is a registered trademark of Oracle Corporation and/or its affiliates. Other names may be trademarks of their respective owners. Type 'help;' or '\h' for help. Type '\c' to clear the current input statement. mysql>これでmysqlのインストールは完了です。quitでログアウトしておきましょう。
mysql> quitEC2インスタンスからGitHubにSSH接続する
デプロイを行う際にGitHubからEC2へコードをクローンする必要があります。
以下のコマンドで公開鍵と秘密鍵のペアを作成しましょう。ssh-keygen -t rsa -b 4096これで.sshディレクトリの配下に鍵ができるので、catで公開鍵の内容を確認しGitHubに登録します。
cat /home/ec2-user/.ssh/id_rsa.pub以下のURLからGitHubに公開鍵を登録しましょう。
https://github.com/settings/keys
これでGithubにアクセスできるはずなので、EC2上からsshコマンドを実行してみましょう。
「Hi!"ユーザー名"」 と表示されればOKです。ssh git@github.comアプリケーションサーバ(unicorn)の設定。
unicornの設定を行うため、まずはローカルでの作業を行います。Gemfileに以下を追記しましょう。
production do の中に記載することで、本番環境でのみunicornを使うことになります。group :production do gem 'unicorn', 'インストールしたいバージョン' endgemのインストールも忘れずに。
bundle installちょっと長いですが、config/unicorn.rbを以下のように編集します。
app_path = File.expand_path('../../', __FILE__) worker_processes 1 working_directory app_path pid "#{app_path}/tmp/pids/unicorn.pid" listen 3000 stderr_path "#{app_path}/log/unicorn.stderr.log" stdout_path "#{app_path}/log/unicorn.stdout.log" timeout 60 preload_app true GC.respond_to?(:copy_on_write_friendly=) && GC.copy_on_write_friendly = true check_client_connection false run_once = true before_fork do |server, worker| defined?(ActiveRecord::Base) && ActiveRecord::Base.connection.disconnect! if run_once run_once = false # prevent from firing again end old_pid = "#{server.config[:pid]}.oldbin" if File.exist?(old_pid) && server.pid != old_pid begin sig = (worker.nr + 1) >= server.worker_processes ? :QUIT : :TTOU Process.kill(sig, File.read(old_pid).to_i) rescue Errno::ENOENT, Errno::ESRCH => e logger.error e end end end after_fork do |_server, _worker| defined?(ActiveRecord::Base) && ActiveRecord::Base.establish_connection endあとはmasterブランチにpushして完了です。
GitHubからコードをクローンする
EC2インスタンスにディレクトリを作り、権限をec2-userに変更します。
sudo mkdir /var/www/ sudo chown ec2-user /var/www/コードをクローンするためにはリポジトリのURLが必要なので、以下の赤枠内のボタンからURLを取得します。
取得したURLでコードをクローンしましょう。cd /var/www/ git clone https://github.com/naoto-ysd/freemarket.gitこの時点で/var/wwwの配下にアプリがクローンされていると思います。
アプリのディレクトリ内に移動し、各種設定を行いましょう。$ pwd /var/www $ ls -l 合計 4 drwxrwxr-x 15 ec2-user ec2-user 4096 5月 31 14:43 アプリ名Swap領域を用意する
Swap領域を用意し、メモリ不足に備えておきましょう。
ホームディレクトリで以下のコマンドを入力。sudo dd if=/dev/zero of=/swapfile1 bs=1M count=512sudo chmod 600 /swapfile1sudo mkswap /swapfile1sudo swapon /swapfile1gemのインストール
一旦アプリをクローンしたディレクトリに移動します。
cd /var/www/アプリ名本番環境でgemを管理するためにbundlerをインストールします。
ローカルで以下のコマンドを実行してbundlerのバージョンを確認しましょう。bundler -vこれで、ローカル側で使っているバージョンが分かりましたので、EC2上でbundlerのバージョンを指定してインストールします。
gem install bundler -v バージョンbundle installも忘れず実行。
bundle install環境変数の設定
パスワードなどのセキュリティに関わる情報は環境変数に設定します。
まずsecret_key_baseを作成しましょう。
EC2上で以下を実行します。cd /var/www/アプリのディレクトリrake secretでcookieの暗号化に文字列を作成します。
このコマンドで生成する文字列は、後から環境変数に設定するのでコピーしておきましょう。rake secret/etc/environmentを編集して環境変数を設定しましょう。
sudo vim /etc/environmentDATABASE_PASSWORD='MySQLのrootユーザーのパスワード' SECRET_KEY_BASE='先程コピーしたsecret_key_base'環境変数を反映させるため、一度ここでログアウトしてから再度EC2にログインてください。
再度ログインしたら、環境変数が設定されているはずなので、envコマンドで確認します。env | grep DATABASE_PASSWORD env | grep SECRET_KEY_BASEポートの解放
現時点ではEC2インスタンスがhttpで通信できない状態です。
インバウンドルールを編集し、ポートを解放してあげましょう。
先程作成したrunicorn.rbでlisten 3000と記述したので、今回デプロイするアプリではポート番号3000を使うことになります。
インバウンドルールにポート番号3000を追加して、作業は完了です。
Railsを起動させる。
Railsを起動させる前にDBの設定を行います。
ローカル環境でdatabase.ymlを編集してproduction: 以下を変更しましょうproduction: <<: *default database: "アプリ名によって異なる。変更不要" username: root password: <%= ENV['DATABASE_PASSWORD'] %> socket: /var/lib/mysql/mysql.sockローカルでの変更をコミットしてGithubにプッシュした後、EC2インスタンス上にコードを反映させます。
git pull origin masterEC2インスタンス上にデータベースを作成してマイグレーションしましょう。
rails db:create RAILS_ENV=production rails db:migrate RAILS_ENV=productionこのままの状態だとアセットファイル(画像やjsのこと)がコンパイルされていないので、ビューが崩れてしまいます。
事前にコンパイルを行っておきましょう。rails assets:precompile RAILS_ENV=productionそれではEC2インスタンスでRailsを起動させます。
アプリのディレクトリに移動してから、ユニコーンを起動させるコマンドでRailsを起動させることができます。
-cオプションで設定ファイルのパスを指定し、-E で本番環境で作動させています。cd /var/www/アプリ名/bundle exec unicorn_rails -c config/unicorn.rb -E production -Dここまで出来ればデプロイできたはずなので、実際にブラウザでアプリにアクセスしてみましょう。
http://"Elastic IP":3000
エラーが起きた場合、以下のファイルにエラーログが出力されているので、こちらを確認してみてください。tail -f /var/www/freemarket/log/unicorn.stderr.logウェブサーバのインストール
ウェブサーバとしてNginxをEC2にインストールします。
sudo yum -y install nginxインストールが終了したら、/etc/nginx/conf.d/rails.confを以下のように編集しましょう。
アプリケーション名やElasticIPは適宜読み替えてください。upstream app_server { server unix:/var/www/アプリケーション名/tmp/sockets/unicorn.sock; } server { listen 80; server_name Elastic IP; client_max_body_size 2g; root /var/www/アプリケーション名/public; location ^~ /assets/ { gzip_static on; expires max; add_header Cache-Control 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; }nginxの権限も変更しておきます。
sudo chmod -R 775 /var/lib/nginxnginxを再起動させて設定ファイルを読み込ませましょう。
sudo service nginx restartunicorn関係の修正
現在はunicorn.rbのlistenという項目に3000が指定されていると思います。
それを以下のように修正し、Githubへプッシュしましょう。listen "#{app_path}/tmp/sockets/unicorn.sock"EC2への反映も忘れずに。
git pull origin masterunicornを再起動させるため、unicornのプロセスIDを確認します。
ps aux | grep unicorn ec2-user 14750 0.0 11.6 504768 117792 ? Sl Jun01 0:02 unicorn_rails master -c config/unicorn.rb -E production -DプロセスID14750をkillしましょう。
kiill 14750これでRailsを再起動させればアプリケーションにアクセスできるはずです。
http://"Elastic IP" (URLにポート番号の指定は不要です。)RAILS_SERVE_STATIC_FILES=1 unicorn_rails -c config/unicorn.rb -E production -DRailsの起動でエラーが出たら
以下の方法でエラーの解決方法を調査してみましょう。
・ログの確認
/var/www/アプリ名/log/unicorn.stderr.log
/var/log/nginx/error.log・以下を再起動してみる
MySQL
Nginx
EC2いったん完結
アプリのデプロイまで出来たため、前回の記事と合わせていったん完結です。
私の気力次第で自動デプロイについての記事も書きます。