- 投稿日:2020-04-01T23:05:55+09:00
Swiper.jsが動作しなかった時の対処法[備忘録]
はじめに
バージョン確認の重要性
Swiper.jsはバージョンによってサポートしてくれるブラウザが違う。ver5.0以降から、IEは完全にサポート対象外になった。今回私はchromeで開発を行っているので最新版でいけると思いきや、挙動が意図したものにならなかったので、4.5.0系を使うことにした。
便利なオプションたち
オプションが豊富で有名なSwiper.js
ここでは、私が参考にした記事を載せておくだけに留めておく。
参考記事
実例12パターン】画像スライダーはSwiper使っておけば間違いない!実用的な使い方を紹介
https://haniwaman.com/swiper/
swiper.js使ってみたからそのオプションについて(v4.1.6)
https://reiwinn-web.net/2018/03/15/swiper-4-1-6/実際のコード
swiper.js$(function(){ var mySwiper = new Swiper('.swiper-container', { slidesPerView: 3, slideToClickedSlide: true, pagination: { el: '.swiper-pagination', type: 'bullets', clickable: true }, navigation: { nextEl: '.swiper-button-next', prevEl: '.swiper-button-prev' }, breakpoints: { 767: { slidesPerView: 1, spaceBetween: 0 } } }); });html.haml.swiper-container.p-2.rounded .swiper-wrapper.p-1 - @posts.each do |post| .events__content.col-sm-6.col-md-4.mb-3 .swiper-slide .card{id: post.id} %label.m-1 - if post.image.present? %img.card-img-top.img-fluid.rounded{src: "#{post.image}"} - else %img.card-img-top.img-fluid.rounded{src: "/assets/noimage.png"} .card-body.event %h5= link_to "#{post.title}", post_path(post.id), class: "event-title stretched-link text-decoration-none" .event__name #{post.user.name} さん .text-right = l post.created_at, format: :long .swiper-button-prev .swiper-button-next .swiper-paginationこれでprevボタンnextボタンを押しても、スライドされない。consoleをみてもエラーはない。ドラッグしながらスクロールすると、一応.swiper-containerに要素が入っていることはわかる。jsファイルは読み込まれているが、メソッドが実行されていない。
階層構造は崩すな
原因がわかった。先ほどのコードは、.swiper-wrapperと.swiper-slidesの間に、.events__content......というクラスが入っている。これが原因だった。Swiper.jsのswiper-container, wrapper, slidesのクラスたちは必ず親子孫の関係でなくてはならなかった。
修正後のコード
html.haml.swiper-container.p-2.rounded .swiper-wrapper.p-1 - @posts.each do |post| .swiper-slide.events__content.col-sm-6.col-md-4.mb-3 .card{id: post.id} %label.m-1 - if post.image.present? %img.card-img-top.img-fluid.rounded{src: "#{post.image}"} - else %img.card-img-top.img-fluid.rounded{src: "/assets/noimage.png"} .card-body.event %h5= link_to "#{post.title}", post_path(post.id), class: "event-title stretched-link text-decoration-none" .event__name #{post.user.name} さん .text-right = l post.created_at, format: :long .card.col-auto .text-left - post.genre_list.each do |genre| .badge.badge-primary{data:{role: "tagsinput"}} = link_to "#{genre}", tag_path(genre), class: 'text-decoration-none text-white' - if user_signed_in? .offset-8.col-auto.card .text-center.likes = render partial: '/posts/posts', locals: {post: post} - if @posts.count >= 4 .swiper-button-prev .swiper-button-next .swiper-paginationこれで正常に動くようになった。
終わりに
私のように、こんなことで何時間も無駄にしないように、皆さんも気をつけてください。
参考記事
【Rails5】「Swiper」を使ってスライダー、カルーセルを作る方法
https://qiita.com/emincoring/items/18d07d0aec5d9836227c
[Rails]Swiperで画像スライド作成
https://qiita.com/yummy888/items/8528c7542f85ae7bbc55サンプル付き!簡単にスライドを作れるライブラリSwiper.js超解説(各種ナビゲーションカスタマイズ編)
https://garigaricode.com/swiper_navigation/
- 投稿日:2020-04-01T22:24:45+09:00
railsのアセットパイプラインと本番環境について(未完成)
アセットパイプライン
基本
開発者が作成したJsやCSSを最終的に統合して、HTMLソースに落とし込めるようにする仕組み。本番環境でのみ行う。
流れ
高級言語のコンパイル(cofeeやSCSS)、開発環境ではここまでしか行わない。本番環境ではここから最後までの処理を行う。
↓
アセットの結合(複数のjsファイルをapplication.jsに統合、cssも同様)
↓
アセット最小化(コメントや改行を無くして圧縮する)
↓
ダイジェストの付与(これをするとファイルにハッシュ値(暗号化された値?)をつけてpublic/assets下に反映される、イメージがつかなければ参考文献をみる)
↓
HTMLでapplication.jsとapplication.cssが読み込まれるマニフェストファイル(application.jsとapplication.cssのこと)
ここに記述することはどのJsやCSSを自身に統合するか
を記述したり、別ファイルに書かれた設定を適用させる。
↓
探索パスを設定することでファイルの統合が簡単になる.
app/asset/とlib/assets/とvender/assets/*に探索パスが設定されている。それらの場所に探索パスが設定されるので、マニフェストファイルはその場所に統合するべき指定のファイルがないかを探す。application.js//= require sliderこの意味はapp/asset/とlib/assets/とvender/assets/*にslider.jsがあるか探し、統合するということ
探索パスを配置する場所の設定を追加したい時はconfig/initializers/assetes.rbで記述してやる。
開発環境と本番環境
上記で示したように開発環境では高級言語のコンパイル(cofeeやSCSS)しか行わないため、jsやscssのファイルが別々に存在している。
↓
なぜならば開発環境では開発しやすいコードやファイルの配置を行うべきだから、ファイルを連結して、改行やコメントを無くしたりするべきではない。しかし本番環境では人間が理解しやすいコードや配置をする必要がなく、むしろスピードが求められるため、ファイルを連結、圧縮している。
参考文献は【Rails】デプロイに強くなるアセットパイプラインまとめ(アセットプリコンパイルで何が起きているか)
config/environments
ここには開発、テスト、本番のアセットパイプラインの設定をする。
設定とは開発環境ではアセットの連結や圧縮を行わないとか。アセットプリコンパイル
本番環境で行われるファイルの連結、圧縮のこと。何度も書きますが本番環境でのみ行われる。
本番環境でのデプロイ
デプロイ時やらないといけないこと
*アセットパイプラインをどうするか
*データベースの設定アセットパイプライン設定
アセットパイプライン設定のconfig/environmentsを行い、探索パスを増やしたければ
config/initializers/assetes.rbに記述。
↓
アセットプリコンパイル(ファイル連結、圧縮)を実施するために以下のコマンドを実施。これで統合されたマニフェストファイルがハッシュ値を持った状態でpublic/assetsに保存されるようになる。rails assets:precompile
データベースの設定
config/database.ymlのなかで各環境でのdb設定を記述できる。主にdatabase名、user名、そのパスワードを記述する。
user名とは本番環境でのSQLに関するユーザーの名前のことであるため、まず本番環境のSQLでログインとデータベース作成が可能なユーザーを作成し、パスワードも設定する。(database.ymlにはパスワードは環境変数として記述して、~/.bash_profileで環境変数定義をしてやる)秘密情報の管理
本番環境にアプリを置くということは外部にアプリを置くということである。しかし外部には後悔したくない秘密情報をアプリに記述したい場合がある。その時はconfig/credential.yml.encに記述してやる。config/credential.yml.encは暗号化されている。この内容をアプリ内で使用する際はcinfig/master.keyによって復号され使用される。
また開発者が記述した秘密情報を新たにcredential.yml.encに追加したい場合も、master.keyによって暗号化されcredential.yml.encに反映される。参考文献は[Rails]credentials.yml.encについてまとめる
Rails5.2から追加された credentials.yml.enc のキホン
- 投稿日:2020-04-01T22:24:45+09:00
railsのアセットパイプラインと本番環境のデプロイについて
アセットパイプライン
基本
開発者が作成したJsやCSSを最終的に統合して、HTMLソースに落とし込めるようにする仕組み。本番環境でのみ行う。
流れ
高級言語のコンパイル(cofeeやSCSS)、開発環境ではここまでしか行わない。本番環境ではここから最後までの処理を行う。
↓
アセットの結合(複数のjsファイルをapplication.jsに統合、cssも同様)
↓
アセット最小化(コメントや改行を無くして圧縮する)
↓
ダイジェストの付与(これをするとファイルにハッシュ値(暗号化された値?)をつけてpublic/assets下に反映される、イメージがつかなければ参考文献をみる)
↓
HTMLでapplication.jsとapplication.cssが読み込まれるマニフェストファイル(application.jsとapplication.cssのこと)
ここに記述することはどのJsやCSSを自身に統合するか
を記述したり、別ファイルに書かれた設定を適用させる。
↓
探索パスを設定することでファイルの統合が簡単になる.
app/asset/とlib/assets/とvender/assets/*に探索パスが設定されている。それらの場所に探索パスが設定されるので、マニフェストファイルはその場所に統合するべき指定のファイルがないかを探す。application.js//= require sliderこの意味はapp/asset/とlib/assets/とvender/assets/*にslider.jsがあるか探し、統合するということ
探索パスを配置する場所の設定を追加したい時はconfig/initializers/assetes.rbで記述してやる。
開発環境と本番環境
上記で示したように開発環境では高級言語のコンパイル(cofeeやSCSS)しか行わないため、jsやscssのファイルが別々に存在している。
↓
なぜならば開発環境では開発しやすいコードやファイルの配置を行うべきだから、ファイルを連結して、改行やコメントを無くしたりするべきではない。しかし本番環境では人間が理解しやすいコードや配置をする必要がなく、むしろスピードが求められるため、ファイルを連結、圧縮している。
参考文献は【Rails】デプロイに強くなるアセットパイプラインまとめ(アセットプリコンパイルで何が起きているか)
config/environments
ここには開発、テスト、本番のアセットパイプラインの設定をする。
設定とは開発環境ではアセットの連結や圧縮を行わないとか。アセットプリコンパイル
本番環境で行われるファイルの連結、圧縮のこと。何度も書きますが本番環境でのみ行われる。
本番環境でのデプロイ
デプロイ時やらないといけないこと
*アセットパイプラインをどうするか
*データベースの設定
*secret_key_baseの設定アセットパイプライン設定
アセットパイプライン設定のconfig/environmentsを行い、探索パスを増やしたければ
config/initializers/assetes.rbに記述。
↓
アセットプリコンパイル(ファイル連結、圧縮)を実施するために以下のコマンドを実施。これで統合されたマニフェストファイルがハッシュ値を持った状態でpublic/assetsに保存されるようになる。rails assets:precompile
データベースの設定
config/database.ymlのなかで各環境でのdb設定を記述できる。主にdatabase名、user名、そのパスワードを記述する。
user名とは本番環境でのSQLに関するユーザーの名前のことであるため、まず本番環境のSQLでログインとデータベース作成が可能なユーザーを作成し、パスワードも設定する。(database.ymlにはパスワードは環境変数として記述して、~/.bash_profileで環境変数定義をしてやる)secret_key_baseの設定
これは本番環境で作成される秘密鍵でcookies整合性確認に使用される。保存方法は環境変数としてSECRET_KEY_BASEに保存する方法とcredentials.yml.encに保存する方法がある。
補足:秘密情報の管理
本番環境にアプリを置くということは外部にアプリを置くということである。しかし外部には後悔したくない秘密情報をアプリに記述したい場合がある。その時はconfig/credential.yml.encに記述してやる。config/credential.yml.encは暗号化されている。この内容をアプリ内で使用する際はcinfig/master.keyによって復号され使用される。
また開発者が記述した秘密情報を新たにcredential.yml.encに追加したい場合も、master.keyによって暗号化されcredential.yml.encに反映される。参考文献は[Rails]credentials.yml.encについてまとめる
Rails5.2から追加された credentials.yml.enc のキホン
- 投稿日:2020-04-01T22:13:59+09:00
ログイン機能つけてくよ。〜Railsチュートリアル8章〜
少しづつ難しくなってきました。今回はログイン機能についてまとめてみます。
足早に来てるけどこうして一個一個確実にアウトプットしてくよ。この章ではログイン・ログアウト機能を実装していきます。
ログインの仕組みはブラウザがログインを保持し、ユーザーによってブラウザが閉じられたら状態を破棄すること。
ログインしたユーザーだけがアクセスできるページや扱える機能を制御する。こうした制限や制御の仕組みを認可モデルという。セッション
HTTPは状態(state)がない(less)。つまりステートレスなプロトコルである。
HTTPによるリクエストの一つ一つはそれより前の情報を全く利用できません。
リクエストが終わると何もかも忘れてしまう健忘症的なプロトコルである。
つまりHTTP自体にはブラウザの別のページへ移動したときにユーザーのIDを保持しておく手段がない。
ユーザーログインが必要なApplicationではセッションと呼ばれる半永続的な接続をコンピュータ間に別途設定を行う。cookies
Railsでセッションを実装する方法として最も一般的なのはcookiesを使う方法である。cookiesとはユーザーのブラウザに保存される小さなテキストデータである。cookiesはあるページから別のページに移動したときも破棄されないのでここにIDなどの情報を保存できる。Applicationはcookies内のデータをデータベースから取り出すことができる。
今回はsessionというRailsのメソッドを使って一時セッションを作成する。この一時セッションはブラウザを閉じると自動的に終了する。
セッションをRESTfulなResourcesとしてモデリングできると。他のRESTfulリソースと統一的に理解できる。
UserリソースとSessionリソースの違い
Userリソース...バックエンドでUserモデルを介してデータベース上の永続的データにアクセスする
Sessionリソース...cookiesを保存場所として使う。
Sessionsコントローラ
Sessionsコントローラの特定のRESTアクションにそれぞれ対応付けしていく。フォームはnewアクションで処理。
sessionsリソースの追加get '/login', to: 'sessions#new' post '/login', to: 'sessions#create' delete '/logout', to: 'sessions#destroyログインフォーム
ログインフォームを整えていく。入力時に誤りがあった場合ログインページをもう一度表示しエラーメッセージを出力する。サインアップページではエラーメッセージに専用のパーシャルを使用したが今回はActive Recordからの自動生成ではないためフラッシュメッセージを使用する。
Sessionフォームにはモデルが存在しないため@userのようなインスタンス変数に相当するものもない。したがって新しいSessionフォームを作成する時はform_forヘルパーに追加の情報を独自に渡さなければならない。
<%= form_for(:session, url: login_path) do |f| %> <%= f.label :email %> <%= f.email_field :email, class: 'form-control' %> <%= f.label :password %> <%= f.password_field :password, class: 'form-control' %> <%= f.submit "Log in", class: "btn btn-primary" %> <% end %>ユーザーの検索と認証
ログイン機能を実装する際にはまず入力が無効な場合の処理を最初に行う。
SessionでのアクションはSessionコントローラへ定義する。
セッションの中にはemailとpasswordの情報が含まれている。def create user = User.find_by(email: params[:session][:email].downcase) if user && user.authenticate(params[:session][:password]) # ユーザーログイン後にユーザー情報のページにリダイレクトする else # エラーメッセージを作成する render 'new' end enduser = User.find_by(email: params[:session][:email].downcase)params[:session][:email]で、セッションの値を取り出し、メールアドレスには小文字しか入力できないため.downcaseで小文字に変換しています。
その後find_byメソッドで入力したemailをカラムに保存されたemailが一致した場合にユーザーに代入している。if user && user.authenticate(params[:session][:password])&&を使って、条件を2つ指定している。
・user: userの中身がデータベースの内容と一致しているかどうか。
・user.authenticate: userに代入されたレコードのパスワードがポストした値と一致しているか
パスワードが登録しているユーザー情報と一致していたらセッションにユーザーIDを登録している。フラッシュメッセージの表示
ログインが失敗した場合にエラーメッセージを実装していく。まずは統合テストを構築する。
$ rails generate integration_test users_loginテストコードの流れ
1.ログイン用のパスを開く
2.新しいセッションのフォームが正しく表示されたことを確認する
3.わざと無効なparamsハッシュを使ってセッション用パスにPOSTする
4.新しいセッションのフォームが再度表示され、フラッシュメッセージが追加されることを確認する
5.別のページ (Homeページなど) にいったん移動する
6.移動先のページでフラッシュメッセージが表示されていないことを確認する実際のテスト
require 'test_helper' class UsersLoginTest < ActionDispatch::IntegrationTest test "login with invalid information" do get login_path #1.ログイン用のパスを開く assert_template 'sessions/new' #2新しいセッションのフォームが正しく表示されたことを確認する post login_path, params: { session: { email: "", password: "" } } ↑#3わざと無効なparamsハッシュを使ってセッション用パスにPOSTする assert_template 'sessions/new' assert_not flash.empty? #4新しいセッションのフォームが再度表示され、フラッシュメッセージが追加されることを確認する get root_path #5のページ (Homeページなど) にいったん移動する assert flash.empty? #6フラッシュメッセージが表示されていないことを確認する end endログイン失敗時の正しい処理
class SessionsController < ApplicationController def create user = User.find_by(email: params[:session][:email].downcase) if user && user.authenticate(params[:session][:password]) # ユーザーログイン後にユーザー情報のページにリダイレクトする else flash.now[:danger] = 'Invalid email/password combination' render 'new' end end失敗するテストをパスさせるには、flashをflash.nowに置き換える。後者は、レンダリングが終わっているページで特別にフラッシュメッセージを表示することができます。flashのメッセージとは異なり、flash.nowのメッセージはその後リクエストが発生したときに消滅します
ログイン
実際にログイン中の状態での有効な値の送信をフォームで正しく扱える用にする。cookiesを使った一時セッションでユーザーをログインできるようにする。
セッションを実装するには通常様々なコントローラやビューでおびただしい数のメソッドを定義する必要がある。Rubyのモジュール機能を使うとそうしたメソッドを一箇所にパッケージ化できる。Sessionsコントローラを生成した時点でSessionヘルパーモジュールも自動生成されている。Applicationコントローラにこのモジュールを読み込ませればどのコントローラでも使える用になる。class ApplicationController < ActionController::Base protect_from_forgery with: :exception include SessionsHelper endinclude...モジュールを呼ぶためのメソッド
log_inメソッド
railsで事前定義済みのSessionメソッドを使って単純なログインを行える用にする。
session[:user_id] = user.idこのコードを実行するとユーザーのブラウザ内の一時cookiesに暗号化済みのユーザーIDが自動で作成される。Sessionメソッドで作成した一時cookiesは一時的に暗号化されこのコードは保護される。攻撃者がたとえこの情報を盗み出すことができてもそれを使って本物のユーザーとしてログインすることはできない。
このセッションでlog_inというヘルパーメソッドを定義できたのでユーザーログインを行ってSessionのcreateアクションを完了し、ユーザーのプロフィールページにリダイレクトする準備ができる。
def create user = User.find_by(email: params[:session][:email].downcase) if user && user.authenticate(params[:session][:password]) log_in user redirect_to user else flash.now[:danger] = 'Invalid email/password combination' render 'new' end end現在のユーザー
ユーザーIDを一時セッションの中に安全におけるようになったので今度はそのユーザーを別のページで取り出すことにする。そのためにはcurrent_userメソッドを定義して、SessionIDに対応するユーザー名をデータベースから取り出せるようにする。
なぜcurrent_userを定義するのか。find_byメソッドを使うということは、使う度にデータベースアクセスが発生する。
データベースに保存されているデータが多いほど検索時間かかるし、無駄にアクセス増やしたくない。
そのためUser.find_byの実行結果をインスタンス変数に保存しておく方法がRailsの慣習である。
よって@current_userへの代入を行う。module SessionsHelper # 渡されたユーザーでログインする def log_in(user) session[:user_id] = user.id end # 現在ログイン中のユーザーを返す (いる場合) def current_user if session[:user_id] @current_user ||= User.find_by(id: session[:user_id]) end end endレイアウトリンクを変更する。
レイアウトがユーザーがログインしているときとそうでないときとで変更できるようにする。まず統合テストを書いていく。# ユーザーがログインしていればtrue、その他ならfalseを返す def logged_in? !current_user.nil? end end<% if logged_in? %> <li><%= link_to "Users", '#' %></li> <li class="dropdown"> <a href="#" class="dropdown-toggle" data-toggle="dropdown"> Account <b class="caret"></b> </a> <ul class="dropdown-menu"> <li><%= link_to "Profile", current_user %></li> <li><%= link_to "Settings", '#' %></li> <li class="divider"></li> <li> <%= link_to "Log out", logout_path, method: :delete %> </li> </ul> </li> <% else %> <li><%= link_to "Log in", login_path %></li> <% end %>レイアウトの変更をテストする
1.ログイン用のパスを開く
2.セッション用パスに有効な情報をpostする
3.ログイン用リンクが表示されなくなったことを確認する
4.ログアウト用リンクが表示されていることを確認する
5.プロフィール用リンクが表示されていることを確認する上記のテストを行う際にはテストユーザーの作成が必要。
Railsではこのようなテスト用データをfixtureで作成できる。testデータベースでtestに必要なデータを読み込んでおくことができる。# 渡された文字列のハッシュ値を返す def User.digest(string) cost = ActiveModel::SecurePassword.min_cost ? BCrypt::Engine::MIN_COST : BCrypt::Engine.cost BCrypt::Password.create(string, cost: cost) endユーザー登録中のログイン
class UsersController < ApplicationController def show @user = User.find(params[:id]) end def new @user = User.new end def create @user = User.new(user_params) if @user.save log_in @user flash[:success] = "Welcome to the Sample App!" redirect_to @user else render 'new' end end private def user_params params.require(:user).permit(:name, :email, :password, :password_confirmation) end endログアウト
アプリケーションで扱う認証モデルでは、ユーザーが明示的にログアウトするまではログイン状態を保てなくてはならない。
SessionsコントローラのアクションはRESTfulルールに従っている。newでログインページを表示し、createでログインを完了するといった具合です。セッションを破棄するdestroyアクションも、引き続き同じ要領で作成できる。
ログアウトメソッドの定義module SessionsHelper # 渡されたユーザーでログインする def log_in(user) session[:user_id] = user.id end . . . # 現在のユーザーをログアウトする def log_out session.delete(:user_id) @current_user = nil end endSessionを破棄する
class SessionsController < ApplicationController def new end def create user = User.find_by(email: params[:session][:email].downcase) if user && user.authenticate(params[:session][:password]) log_in user redirect_to user else flash.now[:danger] = 'Invalid email/password combination' render 'new' end end def destroy log_out redirect_to root_url end endlog_outメソッドは、Sessionsコントローラのdestroyアクションでも同様に使っていく。
ユーザーログアウトのtest
require 'test_helper' class UsersLoginTest < ActionDispatch::IntegrationTest . . . test "login with valid information followed by logout" do get login_path post login_path, params: { session: { email: @user.email, password: 'password' } } assert is_logged_in? assert_redirected_to @user follow_redirect! assert_template 'users/show' assert_select "a[href=?]", login_path, count: 0 assert_select "a[href=?]", logout_path assert_select "a[href=?]", user_path(@user) delete logout_path assert_not is_logged_in? assert_redirected_to root_url follow_redirect! assert_select "a[href=?]", login_path assert_select "a[href=?]", logout_path, count: 0 assert_select "a[href=?]", user_path(@user), count: 0 end endテストでis_logged_in?ヘルパーメソッドを利用できるようにしてあったおかげで、有効な情報をセッション用パスにpostした直後にassert is_logged_in?で簡単にtestできる。
今日はここまで
- 投稿日:2020-04-01T19:47:18+09:00
Rails ウィザード形式導入について 2
はじめに
Rails ウィザード形式導入について 1 はこちらをクリック願います。
チーム開発でフリマサイトを開発致しました。
その際、ユーザーの新規登録画面でウィザード形式を導入致しましたので、内容を整理します。
もうすでにご存知の方、省略の仕方等ご存知でしたら、ご教授願います。前提
- ユーザー情報(User)については 以下 A と記述します。
- 住所情報(Destination)については 以下 B と記述します。
Aの新規登録のnewアクションとビュー
- app/controllers/users/registrations_controller.rbを見てみてください。
- えらいことになっているかと思います・・・
- なんだこれ・・・
app/controllers/users/registrations_controller.rb# frozen_string_literal: true class Users::RegistrationsController < Devise::RegistrationsController # before_action :configure_sign_up_params, only: [:create] # before_action :configure_account_update_params, only: [:update] # GET /resource/sign_up # def new # super # end # POST /resource # def create # super # end # GET /resource/edit # def edit # super # end # PUT /resource # def update # super # end # DELETE /resource # def destroy # super # end # GET /resource/cancel # Forces the session data which is usually expired after sign # in to be expired now. This is useful if the user wants to # cancel oauth signing in/up in the middle of the process, # removing all OAuth session data. # def cancel # super # end # protected # If you have extra params to permit, append them to the sanitizer. # def configure_sign_up_params # devise_parameter_sanitizer.permit(:sign_up, keys: [:attribute]) # end # If you have extra params to permit, append them to the sanitizer. # def configure_account_update_params # devise_parameter_sanitizer.permit(:account_update, keys: [:attribute]) # end # The path used after sign up. # def after_sign_up_path_for(resource) # super(resource) # end # The path used after sign up for inactive accounts. # def after_inactive_sign_up_path_for(resource) # super(resource) # end end
- コメントアウトしている箇所はすでにDevise::RegistrationsControllerで定義されているものです。
- コメントアウト部分を外して上書きすることができます。(メソッドのオーバーライド)
- superはスーパークラス(今回であればDevise)のメソッドを呼び出しています。
とりあえずコメントアウト部分(superクラスの呼び出し部分)を全部消してしまいます・・・
- deviseとUserモデルが紐づくように設定してあるので、superで呼び出してもdeviseは同様の操作を行ってくれるようです。
- 勉強中ですので、super呼び出し方法についてはお待ちください(泣)
newアクションを定義する
app/controllers/users/registrations_controller.rbclass Users::RegistrationsController < Devise::RegistrationsController def new @user = User.new end endそして、対応しているビューも編集する
- 参考程度にみてください。このまま入力するとエラーが出るかも・・・です。
app/views/devise/registrations/new.html.haml.main .title .title__font A情報入力 = form_for(@user, url: user_registration_path) do |f| .name-information .name-information__item .name-information__item__nicname = f.label :name,"ニックネーム" .name-information__name = f.text_field :name,size:26 .email .email__information .email__information__address = f.label :email,"メールアドレス" .email__information = f.email_field :email, autofocus: true, autocomplete: "email",size:26 .password .password__item .password__item__pass = f.label :password,"パスワード" .password__item__note - if @minimum_password_length (#{@minimum_password_length} 文字以上必要です) .password__input .password__description = f.password_field :password, autocomplete: "new-password", size:26 .re-enter .re-enter__item .re-enter__item__pass = f.label :password_confirmation,"確認用パスワード " .re-enter__itempass = f.password_field :password_confirmation, autocomplete: "new-password",size:26 .terms-of-service .terms-of-service__btm %input#submit_button1{:name => "submit", :type => "submit", :value => "次へ進む"}/Aの新規登録のcreateアクションとビュー
- 1ページ目で入力した情報のバリデーションチェックをします。
- 1ページで入力した情報をsessionに保持させます。
- 次のBの登録で使用するインスタンスを生成、当該ページへ遷移するようにします。
createアクションを定義する(追記してください)
app/controllers/users/registrations_controller.rbclass Users::RegistrationsController < Devise::RegistrationsController before_action :configure_sign_up_params, only: [:create] # 省略 def create @user = User.new(sign_up_params) unless @user.valid? flash.now[:alert] = @user.errors.full_messages render :new and return end session["devise.regist_data"] = {user: @user.attributes} session["devise.regist_data"][:user]["password"] = params[:user][:password] @destination = @user.build_destination render :new_destination end protected def configure_sign_up_params devise_parameter_sanitizer.permit(:sign_up, keys: [:attribute]) end end1ページ目で入力した情報のバリデーションチェック
- Userモデルのインスタンスを生成する。
- 1ページ目から送られてきたパラメータをインスタンス変数@userに代入する。
- そのインスタンス変数に対してvalid?メソッドを適用する。
- 送られてきたパラメータが指定されたバリデーションに違反しないかどうかチェックすることができる。
- falseになった場合は、エラーメッセージとともにnewアクションへrenderする。
1ページで入力した情報をsessionに保持させる
- A情報だけではなく、B情報までページ遷移した後に保存するという機能を達成するのが目的です。
- そのために、sessionという機能を用いる。
- sessionとは、ページが遷移しても情報が消えることが無いように、クライアント側で保持をさせておく機能のことをいうようです。
- A情報のバリデーションチェック後、session["devise.regist_data"]に値を代入する。
- この時、sessionにハッシュオブジェクトの形で情報を保持させるために、attributesメソッドを用いてデータを生成する。
- また、paramsの中にはパスワードの情報は含まれているが、attributesメソッドでデータ整形をした際にパスワードの情報は含まれない。
- そこで、パスワードを再度sessionに代入する。
B情報登録で使用するインスタンスを生成、B情報登録ページへ遷移する
- 次ページで、ユーザーモデルに紐づくB情報を入力させるため、該当するインスタンスを生成しておく必要がある。
- そのために、build_destinationで今回生成したインスタンス@userに紐づくDestinationモデルのインスタンスを生成する。
- ここで生成したDestinationモデルのインスタンスは、@destinationというインスタンス変数に代入する。
- そして、B情報を登録させるページを表示するnew_destinationアクションのビューへrenderする。
難しい!でも自作アプリには入れたいです!もうひと頑張り!
続きは次回!
さいごに
日々勉強中ですので、随時更新します。
皆様の復習にご活用頂けますと幸いです。
- 投稿日:2020-04-01T19:15:55+09:00
strftimeとは?
はじめに
新しい会社でインターンをはじめ、最初の方に回ってきた保守開発で、複数の日時を比べる機会がありました。
そこで、いろいろ調べてこのstrftimeを学んだので、アウトプットをかねて記事を書いていきます!(自分の初めてのqiita記事です)strftimeとは?
rubyのstrftimeリファレンスは
時刻を format 文字列に従って文字列に変換した結果を返す
と言っています。そもそも日時ってどうやって取り出すの?
めっちゃいい記事を見つけたのでこちらを参照してください笑
RubyとRailsにおけるTime, Date, DateTime, TimeWithZoneの違い
Time.nowで現在の日時を取得できます。
irb(main):001:0> Time.now
=> 2020-04-01 18:42:47 +0900
今回は、Time.nowからstrftimeを用いて値を呼び出したい形に変える方法についてまとめます。strftimeを使ってみよう!
まずは、rubyのstrftimeリファレンスにある表を眺めて概要を理解しましょう!
この表からいくつか抜粋して、実際の開発や業務で役に立ちそうなものを、コードを用いて紹介していきます!できること1 曜日の取得 %A,%a
irb(main):008:0> t = Time.now
=> 2020-04-01 18:59:14 +0900
irb(main):009:0> t.strftime("%A")
=> "Wednesday"
irb(main):010:0> t.strftime("%a")
=> "Wed"これ以下はtに現在時刻が代入されているものとする
できること2 月の取得 %B,%b
irb(main):011:0> t.strftime("%B")
=> "April"
irb(main):012:0> t.strftime("%b")
=> "Apr"できること3 日時と日付 %c
irb(main):013:0> t.strftime("%c")
=> "Wed Apr 1 18:59:14 2020"できること4 日付の取得 %y/%m/%d
irb(main):016:0> t.strftime("%y/%m/%d")
=> "20/04/01"
irb(main):019:0> t.strftime("%Y/%m/%d")
=> "2020/04/01"
irb(main):018:0> t.strftime("%Y%m%d")
=> "20200401"できること5 日付、それぞれの取得
irb(main):021:0> t.strftime("%Y")
=> "2020"
irb(main):022:0> t.strftime("%m")
=> "04"
irb(main):017:0> t.strftime("%d")
=> "01"最後に
日時、時間、曜日の情報の取得に関して整理できたでしょうか?
また、万が一間違った情報がありましたら教えていただけると嬉しいです!
ご一読いただきありがとうございました!
- 投稿日:2020-04-01T18:31:20+09:00
AWSのRDSが日本語対応にならない場合の対処法
はじめに
Ruby on Rails初心者です。今回はアプリケーションのデプロイ時に苦戦した箇所があったので
勉強のために備忘録として残したいと思います。前提
Rails 5.2.4
問題
・AWSのRDSでMySQLインスタンスを作成
(RDSのMySQLの文字コードは、初期設定は「latin」)
・その後「パラメータグループ」で日本語対応にするも本番環境で
日本語対応されておらず、、解決方法
・EC2にSSHで接続
ssh -i /Users/ユーザー名/.ssh/キーペア名.pem ec2-user@xx.xx.xx.xx・EC2からRDSにアクセス(パスワード要求されます)
mysql -h エンドポイント -P Port -u ユーザ名 -p データベース名・データベースの状態を確認
mysql> show variables like 'char%';・以下のように表示される
+--------------------------+-------------------------------------------+ | Variable_name | Value | +--------------------------+-------------------------------------------+ | character_set_client | utf8mb4 | | character_set_connection | utf8mb4 | | character_set_database | latin1 | | character_set_filesystem | utf8mb4 | | character_set_results | utf8mb4 | | character_set_server | utf8mb4 | | character_set_system | utf8 | | character_sets_dir | /rdsdbbin/mysql-5.7.22.R5/share/charsets/ | +--------------------------+-------------------------------------------+「character_set_database」が「 latin1 」 になっていたので、これを「utf8mb4」に直す
・データベースの文字コード修正mysql> ALTER DATABASE データベース名 default character set utf8mb4;・再度データベースの状態を確認
+--------------------------+-------------------------------------------+ | Variable_name | Value | +--------------------------+-------------------------------------------+ | character_set_client | utf8mb4 | | character_set_connection | utf8mb4 | | character_set_database | utf8mb4 | | character_set_filesystem | utf8mb4 | | character_set_results | utf8mb4 | | character_set_server | utf8mb4 | | character_set_system | utf8 | | character_sets_dir | /rdsdbbin/mysql-5.7.22.R5/share/charsets/ | +--------------------------+-------------------------------------------+これで日本語化に対応できた、、、と思ったができておらず(^^;)
原因はテーブルをすでに作成していたため、テーブルの文字コードも変更しなければ
ならなかった。・テーブルの文字コード変更
mysql> ALTER TABLE テーブル名 CONVERT TO CHARACTER SET utf8md4自分で作成した全てのテーブルを変更し、問題解決した
参考にさせていただいた記事
- 投稿日:2020-04-01T16:35:37+09:00
データの入ったテーブルに対して外部キーが設定されたカラムを追加する
やりたいこと
foosテーブルとbarsテーブルがあったとして
barsテーブルにfoo:references
のカラムを追加したい。
ただし、システムは運用を始めておりbarsテーブルにはデータが入っている。普通に
db/migrate/YYYYMMDDhhmmss_add_foo_to_bars.rbclass AddFooToBars < ActiveRecord::Migration[6.0] def change add_reference :bars, :foo, null: false, foreign_key: true end endで
db:migrate
しようとすると、空のfoo_id
カラムが発生してしまうため、エラーになってしまう。解決策
まずは初期値を設定してカラムを追加する。
default値はfoosテーブルに存在するid
を指定する。db/migrate/YYYYMMDDhhmmss_add_foo_to_bars.rbclass AddFooToBars < ActiveRecord::Migration[6.0] def change add_reference :bars, :foo, null: false, foreign_key: true, default: 1 end end次にDEFAULTの定義を残しておくと気持ち悪いので消す。
db/migrate/YYYYMMDDhhmmss_change_foo_to_bars.rbclass ChangeFooToBars < ActiveRecord::Migration[6.0] def change change_column_default(:bars, :foo_id, nil) end endこれでデータの入ったテーブルに外部キーが設定されたカラムを追加できます。
- 投稿日:2020-04-01T16:02:52+09:00
Strong Parametersでネストする場合の注意点
params = { title: "タイトル", content: { header: "見出し", body: "内容" }, author: "太郎" }みたいなパラメータをpermitしてあげるときこの順番通りに実装しようとすると
params.permit(:title, content: [:header, :body], :author)となるが、これだとsyntax errorになる
理由はネストする場合はそのネストするパラメータを最後に持ってこないといけないため。
正解はこれparams.permit(:title, :author, content: [:header, :body])
- 投稿日:2020-04-01T13:30:02+09:00
ActiveModelSerializer + #Rails の Controller render で json /. json_api の adapter を無効化してデフォルト設定を使う ( disable json adapter and reset to default )
- 投稿日:2020-04-01T12:07:12+09:00
Railsでlink_to deleteメソッドが動かない
rails5.2を使ってアプリを実装中にハマったエラーです。
なかなか解決策が見つからず困ったのでメモとして置いておきます。状況
rootテーブルに投稿されたレコードを削除するため、実装したが削除されない。
リンクは表示されてクリックできるけどアクションが発火しない。加えてエラーも出ない。
ログを見るとGETで送られている。<%= link_to '削除', "#{@root.id}", method: :delete %>基本的な確認はしてみた。
route.rb、controllerの記述はちゃんとできてる。
rails routesを確認して、HTTPメソッドは来ている。htmlもdeleteになっている。route.rb resources :roots roots_controller.rb def destroy root= Root.find(params[:id]) root.destroy redirect_to root_path end試したこと
application.js
//= require rails-ujs
があるか確認。→ 記述はあったのでパス。
Turbolinksのバージョンを見る
→ Githubの投稿を読んで参考にしてみた。
https://gist.github.com/JunichiIto/791ee8b6c9eb4ac639d2141465f89fc4・・・どうもうまくいかない。
解決方法
あれこれ修正を繰り返していたら「ActionController::InvalidAuthenticityToken」というエラーに当たる。
これがきっかけ。■原因
RailsのCSRF対策が堅固なので外部からのアクセスをはじく設定がデフォルトになっていたため。
外部サイトからのAPIリクエストと認識されたようで、受け付けないらしい。
※RailsのCSRF対策についてはここでは割愛します。■実装1
destroyアクションを実施したいコントローラーに追記する。
protect_from_forgery の記述を使います。(詳細は調べてください)今回はRootsコントローラーからdestoryアクションを除外 1 class RootsController < ApplicationController 2 protect_from_forgery :except => [:destroy] 3 4 def index ///////以下省略////////■実装2
link_toをbutton_toに修正。(なぜかlink_toだと動かなかった)<%= link_to '削除', "#{@root.id}", method: :delete %> ↓ <%= button_to '削除', "#{@root.id}", method: :delete %>■結果
無事削除とredirect_toが動きました。最後に
今回はこの実装で投稿削除ができました。RailsのCSRF対策で見えにくいデフォルトの挙動などもあるので公式ガイドなどをチェックをされると良いと思います。
destroyアクションが効かない、deleteメソッドも来ている、コードもあっている、ときのエラーで本当に焦りましたが、エラーが解決の糸口でした。参考になれば幸いです。参考
https://qiita.com/chobi9999/items/2b59fdaf3dd8f2ed9268
http://takayuki-inoue.hatenablog.com/entry/2018/01/12/105846
https://qiita.com/ayacai115/items/ec7a621ec73692065d7a
https://qiita.com/natu_kumo_/items/8ef3343fda6715ed1d1a
- 投稿日:2020-04-01T09:15:05+09:00
#Rails / ActiveRecord / 複数形の validates メソッドと 単数形の validate メソッドの違いは? 前者が標準のvalidatorで後者がカスタムのvalidator。
びっくりするぐらい分かりにくいが、きっと命名的に苦慮の末だったのだろう。
validates (標準)
おなじみのやつ。
validate (カスタム)
こちらは自分でModelにメソッドを作って、ちっちゃなカスタムバリデーターを作る。
Active Record Validations — Ruby on Rails Guides
Original by Github issue
- 投稿日:2020-04-01T02:30:36+09:00
Library not loaded: libssl.1.1.dylib (LoadError) 発生時の対処策
状況
macOS catalina で railsアプリの開発環境を整え終わって、
Windows10環境で開発してたWebアプリをクローンし、いざrails server
実行だ!
と意気込んでいたら、見た事のないエラーに困惑…解決はできたものの、いろいろと調べたら闇が深そうだったので、
自分用にメモを残しておきます。ついでに同じエラーに悩む方の助けになれば幸いです!
エラー内容
zshdlopen(/Users/kirimaro/.rbenv/versions/2.5.3/lib/ruby/gems/2.5.0/gems/mysql2-0.5.3/lib/mysql2/mysql2.bundle, 9): Library not loaded: libssl.1.1.dylib (LoadError) Referenced from: /Users/kirimaro/.rbenv/versions/2.5.3/lib/ruby/gems/2.5.0/gems/mysql2-0.5.3/lib/mysql2/mysql2.bundle Reason: image not found - /Users/kirimaro/.rbenv/versions/2.5.3/lib/ruby/gems/2.5.0/gems/mysql2-0.5.3/lib/mysql2/mysql2.bundle
OpenSSL@1.1
のインストールmacOS catalina はデフォルトのSSLがLibreSSL 2.8.3が設定されています。
試しにopenssl version
を実行すると、LibreSSL 2.8.3
と出力されはずです。
上記エラーの原因はこいつです。
gem "mysql2"
はOpenSSLと依存関係にあり、LibreSSLがデフォルトだとLibrary not loaded: libssl.1.1.dylib
といったロードエラーが発生します。これを解消するために、まず
OpenSSL@1.1
をインストールします。尚、
OpenSSL@1.1
はHomebrewでインストールを行いますが、
Homebrewのインストール方法については、他で調べれば記事が大量だと思うのでここでは割愛させていただきます!
※Homebrewの利用にはXcodeが必須となりますので、インストールしていない方は先にインストールしておきましょう。既にHomebrewをインストール済みの方は、以下のコマンドを実行します。
zsh% brew install openssl@1.1
インストールが完了したら、
brew info openssl
を実行します。すると
OpenSSL@1.1
について以下のような情報が表示されます。zsh% brew info openssl openssl@1.1: stable 1.1.1d (bottled) [keg-only] Cryptography and SSL/TLS Toolkit https://openssl.org/ /usr/local/Cellar/openssl@1.1/1.1.1d (7,983 files, 17.9MB) Poured from bottle on 2020-03-30 at 20:49:11 From: https://github.com/Homebrew/homebrew-core/blob/master/Formula/openssl@1.1.rb ==> Caveats A CA file has been bootstrapped using certificates from the system keychain. To add additional certificates, place .pem files in /usr/local/etc/openssl@1.1/certs and run /usr/local/opt/openssl@1.1/bin/c_rehash openssl@1.1 is keg-only, which means it was not symlinked into /usr/local, because openssl/libressl is provided by macOS so don't link an incompatible version. If you need to have openssl@1.1 first in your PATH run: echo 'export PATH="/usr/local/opt/openssl@1.1/bin:$PATH"' >> ~/.zshrc For compilers to find openssl@1.1 you may need to set: export LDFLAGS="-L/usr/local/opt/openssl@1.1/lib" export CPPFLAGS="-I/usr/local/opt/openssl@1.1/include" For pkg-config to find openssl@1.1 you may need to set: export PKG_CONFIG_PATH="/usr/local/opt重要なのは、
echo 'export PATH="/usr/local/opt/openssl@1.1/bin:$PATH"' >> ~/.zshrc
で、
これをzshにコピペして実行する事で、デフォルトのSSLがOpenSSLへ変更されます。実は、エラーの解消自体はOpenSSLをインストールしていれば、デフォルトに設定していなくても問題なく解決できます。
私自身まだそこまで詳しくないのですが、開発ツールなどの多くがまだまだOpenSSLへ依存している状況もあるようなので、
デフォルトに指定しておいたほうが無難なのかなと思います。正しく切り替わったか確認したい場合は、zshを再起動したうえで
openssl version
を入力してみて下さい。
OpenSSL @1.1.1d
といった感じで、デフォルトSSLが切り替わっている事が確認できると思います。
mysql2
ビルド時に必要となるlib/includeのPathを環境変数に追加
~/.zshenv
ファイルをviなどのテキストエディタで開き、
brew info openssl
実行時に表示される下記パスを追加します。保存したら反映するために、zshを再起動します。
export LDFLAGS="-L/usr/local/opt/openssl@1.1/lib" export CPPFLAGS="-I/usr/local/opt/openssl@1.1/include"bundle configにビルドパスを追加
railsアプリのルートディレクトリへ移動し、zshから下記コマンドを実行します。
zsh% bundle config build.mysql2 --with-ldflags=$LDFALGS --with-cppflags=$CPPFLAGSこれで、bundle installを実行した際、mysql2のインストール時にビルドオプションとして、opensslのlib/includeが読み込まれます。
Railsアプリからすでにインストール済みの
mysql2
をアンインストール下記コマンドを実行し、インストール済みのmysql2を削除します。
zsh% bundle exec gem uninstall mysql2
bundle install を実行
既に
bundle config
でビルドオプションを設定済みですので、bundle install
若しくはbundle
のみでインストール可能です。zsh% bundle install
これで、ロードエラーが解消され、正常にサーバーが起動されると思います。
デフォルトSSLをLibreSSLに戻したい時
デフォルトSSLをLibreSSLに戻したい場合は、
~/.zshrc
に追加された
export PATH="/usr/local/opt/openssl@1.1/bin:$PATH"
を削除・保存し、zshを再起動すると、
LibreSSLがデフォルトSSLに戻ります。
- 投稿日:2020-04-01T02:30:36+09:00
Library not loaded: libssl.1.1.dylib (LoadError) 発生時の解決方法
状況
macOS catalina で railsアプリの開発環境を整え終わって、
Windows10環境で開発してたWebアプリをクローンし、いざrails server
実行だ!
と意気込んでいたら、見た事のないエラーに困惑…解決はできたものの、いろいろと調べたら闇が深そうだったので、
自分用にメモを残しておきます。ついでに同じエラーに悩む方の助けになれば幸いです!
エラー内容
zshdlopen(/Users/kirimaro/.rbenv/versions/2.5.3/lib/ruby/gems/2.5.0/gems/mysql2-0.5.3/lib/mysql2/mysql2.bundle, 9): Library not loaded: libssl.1.1.dylib (LoadError) Referenced from: /Users/kirimaro/.rbenv/versions/2.5.3/lib/ruby/gems/2.5.0/gems/mysql2-0.5.3/lib/mysql2/mysql2.bundle Reason: image not found - /Users/kirimaro/.rbenv/versions/2.5.3/lib/ruby/gems/2.5.0/gems/mysql2-0.5.3/lib/mysql2/mysql2.bundle
OpenSSL@1.1
のインストールmacOS catalina はデフォルトのSSLがLibreSSL 2.8.3が設定されています。
試しにopenssl version
を実行すると、LibreSSL 2.8.3
と出力されはずです。
上記エラーの原因はこいつです。
gem "mysql2"
はOpenSSLと依存関係にあり、LibreSSLがデフォルトだとLibrary not loaded: libssl.1.1.dylib
といったロードエラーが発生します。これを解消するために、まず
OpenSSL@1.1
をインストールします。尚、
OpenSSL@1.1
はHomebrewでインストールを行いますが、
Homebrewのインストール方法については、他で調べれば記事が大量だと思うのでここでは割愛させていただきます!
※Homebrewの利用にはXcodeが必須となりますので、インストールしていない方は先にインストールしておきましょう。既にHomebrewをインストール済みの方は、以下のコマンドを実行します。
zsh% brew install openssl@1.1
インストールが完了したら、
brew info openssl
を実行します。すると
OpenSSL@1.1
について以下のような情報が表示されます。zsh% brew info openssl openssl@1.1: stable 1.1.1d (bottled) [keg-only] Cryptography and SSL/TLS Toolkit https://openssl.org/ /usr/local/Cellar/openssl@1.1/1.1.1d (7,983 files, 17.9MB) Poured from bottle on 2020-03-30 at 20:49:11 From: https://github.com/Homebrew/homebrew-core/blob/master/Formula/openssl@1.1.rb ==> Caveats A CA file has been bootstrapped using certificates from the system keychain. To add additional certificates, place .pem files in /usr/local/etc/openssl@1.1/certs and run /usr/local/opt/openssl@1.1/bin/c_rehash openssl@1.1 is keg-only, which means it was not symlinked into /usr/local, because openssl/libressl is provided by macOS so don't link an incompatible version. If you need to have openssl@1.1 first in your PATH run: echo 'export PATH="/usr/local/opt/openssl@1.1/bin:$PATH"' >> ~/.zshrc For compilers to find openssl@1.1 you may need to set: export LDFLAGS="-L/usr/local/opt/openssl@1.1/lib" export CPPFLAGS="-I/usr/local/opt/openssl@1.1/include" For pkg-config to find openssl@1.1 you may need to set: export PKG_CONFIG_PATH="/usr/local/opt重要なのは、
echo 'export PATH="/usr/local/opt/openssl@1.1/bin:$PATH"' >> ~/.zshrc
で、
これをzshにコピペして実行する事で、デフォルトのSSLがOpenSSLへ変更されます。実は、エラーの解消自体はOpenSSLをインストールしていれば、デフォルトに設定していなくても問題なく解決できます。
私自身まだそこまで詳しくないのですが、開発ツールなどの多くがまだまだOpenSSLへ依存している状況もあるようなので、
デフォルトに指定しておいたほうが無難なのかなと思います。正しく切り替わったか確認したい場合は、zshを再起動したうえで
openssl version
を入力してみて下さい。
OpenSSL @1.1.1d
といった感じで、デフォルトSSLが切り替わっている事が確認できると思います。
mysql2
ビルド時に必要となるlib/includeのPathを環境変数に追加
~/.zshenv
ファイルをviなどのテキストエディタで開き、
brew info openssl
実行時に表示される下記パスを追加します。保存したら反映するために、zshを再起動します。
export LDFLAGS="-L/usr/local/opt/openssl@1.1/lib" export CPPFLAGS="-I/usr/local/opt/openssl@1.1/include"bundle configにビルドパスを追加
railsアプリのルートディレクトリへ移動し、zshから下記コマンドを実行します。
※特定のアプリにのみビルドオプションを指定したい場合は、該当アプリのルートディレクトリにいる状態でローカルの方のコマンドを実行してください!zsh#グローバル(別のアプリでmysql2をインストールする場合も、ビルドオプションが適用される) % bundle config build.mysql2 --with-ldflags=$LDFALGS --with-cppflags=$CPPFLAGS #ローカル(現在ルートディレクトリとなっているアプリでのみ、mysql2インストール時にビルドオプションが渡される) % bundle config --local build.mysql2 --with-ldflags=$LDFALGS --with-cppflags=$CPPFLAGSこれで、bundle installを実行した際、mysql2のインストール時にビルドオプションとして、opensslのlib/includeが読み込まれます。
Railsアプリからすでにインストール済みの
mysql2
をアンインストール下記コマンドを実行し、インストール済みのmysql2を削除します。
zsh% bundle exec gem uninstall mysql2
bundle install を実行
既に
bundle config
でビルドオプションを設定済みですので、bundle install
若しくはbundle
のみでインストール可能です。zsh% bundle install
これで、ロードエラーが解消され、正常にサーバーが起動されると思います。
デフォルトSSLをLibreSSLに戻したい時
デフォルトSSLをLibreSSLに戻したい場合は、
~/.zshrc
に追加された
export PATH="/usr/local/opt/openssl@1.1/bin:$PATH"
を削除・保存し、zshを再起動すると、
LibreSSLがデフォルトSSLに戻ります。
- 投稿日:2020-04-01T01:41:13+09:00
【Rails】HerokuでAWS s3に画像をアップロードしようとしたら<Message>Access Denied</Message>
事前準備
Railsでcarrierwaveを使ってAWS S3に画像をアップロードする手順を画像付きで説明する
概要についてはこちらの記事がとても分かりやすかったので参考にさせていただきました。
ただしこのまま
$ git push
すると、アクセスキーがアップロードされてしまうので注意です。
アクセスキーの隠し方については、heroku 環境変数
とかgem 'dotenv-rails'
、$ heroku config:set ACCESS_KEY=aaaaaa
とか調べると出てくると思います。この記事を読むべき人
- https://myapp.herokuapp.com で画像をs3にアップロードしようとしてもうまくいかない
$ heroku logs
したら<Message>Access Denied</Message>
って言われるこの状況の人にはお役に立てるかもしれません。
手順
IAMのユーザーのARNを取得する
- 「AWSマネジメントコンソール」で「セキュリティ、ID、およびコンプライアンス /IAM」を選択
- 「IAMリソース」の「ユーザー: 2」を選択(数字は人それぞれ)
- 「ユーザー」を選択
- 「ユーザーの ARN」をコピーする
パブリックアクセスのブロックをオフにする
- 「AWSマネジメントコンソール」で「ストレージ /s3」を選択
- バケットを選択
- 「アクセス権限」タブを選択
- 「ブロックパブリックアクセス」タブを選択(デフォルトで選択されている)
- 全てのブロックをオフにする
バケットポリシーを使用する
- 「ブロックパブリックアクセス」から「バケットポリシー」タブに切り替える
- 「バケットポリシーエディター」に以下を適用して、保存する
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Principal": { "AWS": "arn:aws:iam::111111111111:user/IAMユーザー名" }, "Action": [ "s3:GetObject", "s3:PutObject", "s3:PutObjectAcl" ], "Resource": "arn:aws:s3:::バケット名/*" } ] }
"arn:aws:iam::111111111111:user/IAMユーザー名"
はコピーしてきたIAMユーザーのARN"Resource": "arn:aws:s3:::バケット名/*"
にバケット名を入力する以上
これでいけるはず。
参考記事
- 投稿日:2020-04-01T01:03:05+09:00
deviseに新しいカラムを追加したけどviewsに表示されない
deviseで作ったusersテーブルに新しくnameカラムを追加、新規登録画面にnameを入れるフィールドを作ったが、なぜかviewsで表示されない問題が解決したので備忘録も兼ねて記事に致します。この記事で少しでも参考になれば幸いです。
結論から申し上げますと、i18nを使うためにはi18n化されたviewsファイルでなきゃ駄目なようです
①自分はdeviseのviewsファイルを作成する際に以下コマンドで作成しました。
rails g devise:views users
②そして日本語化もしたかったのでlocaleファイルも作成
rails g devise:i18n:locale ja
①のコマンドではviewsファイルがi18n化されておらず②と噛み合っていなかったことで、nameフィールドがviewsに表示されなかったと思われます。なので①のファイルを作り直しました。
rails g devise:i18n:views users
以後、無事にviewsに表示されてめでたしめでたし。
- 投稿日:2020-04-01T00:00:16+09:00
docker上でRailsアプリを動かす際に、localhostでアクセスするためのオプション
はじめに
学習環境を用意するにおいて、コンテナ上に開発環境が用意できることで、
・ホストPCを汚すことなく環境を構築できる
・異なるPC間で同じ環境を使いまわせる
・格好いいと感じるといった理由からRailsアプリをコンテナ上で作って動かしてみましたが、ホストからの動作確認で引っかかったのでメモします。
※動かしたのはscaffoldレベルのアプリです先にまとめ
先に問題と解決をまとめて書いておきます
- 問題
- コンテナ内で起動したRailsアプリにホストからアクセスできない
- 解決方法
- Railsアプリを立ち上げる際に、
-b 0.0.0.0
をオプションとしてつける以下、やったこと
まとめにたどり着くまでの状況をつらつらと
準備
ポートフォワードの設定をしてコンテナを立ち上げる
(ホスト)$ docker container run -it -p 30000:3000 /bin/bashコンテナ内でアプリを作る
(コンテナ)# rails new scaffold_sample (コンテナ)# bin/rails db:createデータベースを作成無事できたことを確認した後にアプリケーションを起動
(コンテナ)# bin/rails server上記手順で起動したアプリにアクセスできない
ホストからlocalhost:30000(30000はポートフォワードの設定)にアクセスしてもアプリケーションからの応答はなし
ホストのターミナルからcurlを実行してもエラー
コンテナからlocalhost宛にcurlを実行すると正常な(期待する)htmlが返却される解決手段
アプリケーションの起動時に
-b 0.0.0.0
をオプションとしてつける(コンテナ)# bin/rails server -b 0.0.0.0するとホスト側のブラウザからアプリケーションにアクセスできるようになった
「localhost:30000」「127.0.0.1:30000」「0.0.0.0:30000」のどれでもlocalhostにアクセスできていたオプションの値について
上記の通り、
-b 0.0.0.0
を指定することでによってホストからのアクセスは可能になったが
-b 127.0.0.1
や-b localhost
ではホストからアクセスできるようにはならなかった個人的なメモとして
0.0.0.0や127.0.0.1の持つ意味や、コンテナからみた自分のIP、コンテナからみたホストのIP、ホストから見たコンテナのIPなどが、
ネットワークのオプションとともにどのように振る舞うのかを学ばなければならないと感じた