- 投稿日:2020-09-13T23:07:39+09:00
herokuでのデプロイの仕方
【概要】
1.手順
2.方法
1.手順
❶brew tap heroku/brew && brew install heroku
❷gem 'rails_12factor'
❸heroku用ファイルの作成
❹heroku用DBの作成
❺環境変数の設定
❻heroku上でmasterにpush
❼heroku上でマイグレーションの実施
2.方法
❶brew tap heroku/brew && brew install heroku
ターミナル% brew tap heroku/brew && brew install heroku
を実行しましょう!ミスしないようにherokuに公開したいアプリの該当ファイルで行うことをお勧めします!
そして% heroku login --interactive
でherokuにログインしておきます!❷gem 'rails_12factor'
gemfilegroup :production do gem 'rails_12factor' endと記載し、% bundle installをします!
そしてmasterにコミットしておきます。❸heroku用ファイルの作成
ターミナル% heroku create *****でherokuに公開したいアプリの名前を作成します。
❹heroku用DBの作成
ターミナル% heroku addons:add cleardb
と記載しデーターベースを作成します。
ターミナル% heroku config | grep CLEARDB_DATABASE_URL
これにより、CLEARDB_DATABASE_URLが出てくるので、使用状況によりmysql2を使用している方は、変更しましょう。
>変更方法<
ターミナル% heroku config:set DATABASE_URL = 'mysql2:*****'****の部分は% heroku config | grep CLEARDB_DATABASE_URLでてきたものをコピペします。
❺環境変数の設定
ターミナル% heroku config:set RAILS_MASTER_KEY=`cat config/master.key`
こうすることで、パスワードをファイルの中に書き込まず、見られないようにしてサイトを見るようにできます。
❻heroku上でmasterにpush
ターミナル% git push heroku master
こちらでherokuにpushできます。
❼heroku上でマイグレーションの実施
ターミナル% heroku run rails db:migrate
DBを❹で作っているのでそれをローカルと同じようにherokuでもマイグレーションしていきます。
これでherokuにアプリを公開できるようになります。
ただパスワードを設定していないので誰でもそのサイトを覗ける状態になっているので注意してください。
環境変数はあくまでも自分のサイトを乗っ取られないようにするためものです。
- 投稿日:2020-09-13T22:26:34+09:00
【Rails】データを削除する様々な方法
早見表
メソッド 説明 削除する範囲 destroy 一件のデータを削除 対象データと関連データを削除 destroy_all 複数データを削除 対象データと関連データを削除 delete 一件のデータを削除 対象データのみ削除 delete_all 複数データを削除 対象データのみ削除
関連するデータ
dependent: :destroy
で依存関係にあるデータのこと使い方
# destroyメソッド User.find(1).destroy # destroy_allメソッド User.where(id: 1..5).destroy_all # deleteメソッド User.find(1).delete # delete_allメソッド User.where(id: 1..5).delete_all
- 投稿日:2020-09-13T20:22:29+09:00
[heroku] run rails db:migrateがうまくいかない
環境
・Rails 6.0.3.2
・mysql Ver 14.14 Distrib 5.6.47
・osx10.15
・herokuへデプロイはじめに
Rails
でアプリを作成しheroku
へアップロードするときにうまくいかなかった時の対応です。
開発環境ではMySQL
でheroku
ではDBがPostgreSQL
のためその対応が必要。
その途中段階でエラーが生じた。
順番に書いていきます。PostgreSQLへの対応
まずは
Gemfile
へ以下を記述。本番環境でPostgreSQL
を使うというものです。自分は一番下に書きました。group :production do gem 'pg' endGemfileを変更したので忘れずにbundle installをします。
まずここで一つ目のエラーでました。そのままbundle install
すると自分の開発環境にはPostgreSQL
がないのでエラー発生。対応は
group :produciton end
のところを飛ばすコマンドをターミナルで実行します。$ bundle install --without productionデータベースへ接続する記述をconfigフォルダの中にある
database.yml
へします。
一番下へ追記しました。production: <<: *default adapter: postgresql encoding: unicode pool: 5自分の場合は記述は以上でした。
参考になった記事はコチラです!
【初心者向け】railsアプリをherokuを使って確実にデプロイする方法【決定版】
・https://qiita.com/kazukimatsumoto/items/a0daa7281a3948701c39herokuへデプロイ
今回ここは割愛します。
デプロイ完了まで進みます。ここでdb:migrate
heroku run rails db:migrate
をしますがエラー発生!
いろいろ見ているうちにこのエラーにやっと出会う。。。ターミナルには中ほどに以下のような記述が。
Caused by: PG::ConnectionBad: could not connect to server: No such file or directory Is the server running locally and accepting connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?原因
調べてみると単純なことで
heroku
にはデフォルトではPostgreSQL
が入ってないので、追加してあげる必要があるということです!
なんと!!!!
まだまだ慣れてないのでこの単純なことに気づけませんでした。。。。対応
ターミナルで
PostgreSQL
を追加するコマンド$ heroku addons:create heroku-postgresqlその後に
$ heroku run rails db:migrateそうするとマイグレーションが完了しました!
別のところが誤っていると思い全然違うことをして数時間を費やしてしまいましたが、単純なことでした!
無事アプリが動作し完了しました!参照
【初心者向け】railsアプリをherokuを使って確実にデプロイする方法【決定版】
・https://qiita.com/kazukimatsumoto/items/a0daa7281a3948701c39【Rails】「heroku run rake db:migrate」を実行しようとすると発生するエラーについて
・https://qiita.com/suzuki-x/items/b878723080aea1a673ed
- 投稿日:2020-09-13T19:37:13+09:00
【Rails】ビューに画像を表示する方法
初投稿です。
至らぬ点もあるかと思いますので暖かい目で見守っていただけると幸いです・・・Railsで画像を表示する方法にかなり手こずったのでメモとしての記録です。
それでは早速参りましょう!※haml・scssで記述しています。
画像を表示する方法
まずは、スタンダードに画像を表示する方法。
haml・scssどちらに書いても表示されるみたいです。
どっちに書くのが正解なのと思うところです。個人的な印象としては画像を背景として使いたい時、
例えば画像の上にテキスト情報表示したい時とか。
そんなときは、background-imageとしてscssに記述したほうが良さげ。
ここの違いよくわからないので違いがわかる方いたらご教授いただきたいですまず、表示する画像がないといけません。
app/assets/images
こちらのディレクトリーに表示したい画像を格納して準備完了です。hamlに記述する場合
ファイル名.html.haml= image_tag ("画像名.jpg")これじゃまだ表示できないんですよね。
widthとheightを設定してあげないと表示されません。
そんな時は、scssに画像を整える記述を書く必要があります。_ファイル名.scssimg { width: 100%; height: 100%; }こんな感じで、width: 100%;とheight: 100%;を指定すると無事表示されます。
今回の場合は「%」ですが「px」でも可能!
hamlで書く時は”= image_tag”これが必須ですね。scssに記述する場合
_ファイル名.scss.クラス名 { height: 560px; width: 100%; background-image: image-url("ファイル名.jpg"); background-size: cover; background-repeat: no-repeat; background-position: top center; }こんな感じで書くと表示できます。
background-sizeとかその辺のプロパティ書かないと、
画像が「ばぁぁぁぁあぁぁん」ってなります。(悲惨)
あとは、widthとheightの設定も必要です。
実装したいイメージにあったプロパティを選択する必要があります。本番環境でのみ画像が表示されない
ローカル環境で表示されるのに、本番環境で表示されない・・・
なんてこともあります。表示できないときのコードがこちら
_ファイル名.scss.クラス名 { height: 560px; width: 100%; background-image: url("ファイル名.jpg"); background-size: cover; background-repeat: no-repeat; background-position: top center; }上のコードと見比べて違うところは
_ファイル名.scss.クラス名 { background-image: url("ファイル名.jpg"); }この部分です。
この書き方だと、ローカルでは表示できるけど、本番では表示されません。_ファイル名.scss.クラス名 { background-image: image-url("ファイル名.jpg"); }このように修正することでで本番でもローカルでも表示できるようになります。
データベースにある画像を表示する方法
例えば、商品を登録するときに画像も登録することがあります。
登録した画像を表示したい!!そんな時の方法です。◇条件1◇画像は別テーブルで保存する場合
別テーブルで保存する理由は、複数枚画像を登録するためです。
一枚だけ登録する場合は、テーブルを分ける必要はないかと思います。コントローラー名.rbdef index @items = Item.includes(:item_images).order("created_at DESC").limit(5) endこんな感じで情報を取得。
item_imagesは画像を保存している箇所です。ファイル名.html.haml- @items.each do |item| #eachで展開 = image_tag item.item_images[0].image.url_ファイル名.scssimg { width: 100%; height: 100%; }このように書くと表示できました。
正直、めっちゃ記述長い・・・そんな印象
[0]→画像は配列で格納されているみたいで何枚目かの指定をする必要があります。◇条件2◇画像は別テーブルで保存しない場合
html.erbの記載となります。
コントローラー名.rbdef index @items = Item.order("created_at DESC").page(params[:page]).per(5) endこんな感じで情報を取得。
ファイル名.html.erb<% @items.each do |item| %> <%= image_tag item.image.to_s, :size =>'220x220'%>ちゃっかり、ファイル名.html.erb内でサイズ指定しちゃっています。
これで表示できました他に、表示する方法あればご教授いただきたいです
- 投稿日:2020-09-13T19:04:05+09:00
(ギリ)20代の地方公務員がRailsチュートリアルに取り組みます【第8章】
前提
・Railsチュートリアルは第4版
・今回の学習は3周目(9章以降は2周目)
・著者はProgate一通りやったぐらいの初学者基本方針
・読んだら分かることは端折る。
・意味がわからない用語は調べてまとめる(記事最下段・用語集)。
・理解できない内容を掘り下げる。
・演習はすべて取り組む。
・コードコピペは極力しない。
第8章はログインと認証システムの開発・第3段回目、基本的なログイン機構を実装していきます。(第9章でさらに発展させていきます)
情報技術の用語が飛び交いますので、それぞれの用語の意味・動作も理解しながら進めていきましょう。
本日のBGMは趣向を変えて。
TVアニメ「ゆるキャン△」オリジナル・サウンドトラック
やっと涼しくなってきました。キャンプに最適なシーズンです。コーディングで疲れた眼と頭のリフレッシュに行きましょう。
【8.1.1 Sessionsコントローラ 演習】
1. GET login_pathとPOST login_pathとの違いを説明できますか? 少し考えてみましょう。
→ GETはログインページのビュー取得(newアクション)、POSTはフォームに入力したデータを送信してログインを実行(createアクション)。
2. ターミナルのパイプ機能を使ってrails routesの実行結果とgrepコマンドを繋ぐことで、Usersリソースに関するルーティングだけを表示させることができます。同様にして、Sessionsリソースに関する結果だけを表示させてみましょう。現在、いくつのSessionsリソースがあるでしょうか? ヒント: パイプやgrepの使い方が分からない場合は Learn Enough Command Line to Be Dangerousの Section on Grep (英語) を参考にしてみてください。
→ パイプ機能:(コマンド) | (コマンド) のようにコマンド同士を繋ぐ機能。
grepコマンド:ファイル中の文字列を検索するコマンド。
ということで下記。signupが入ってしまうのは仕方ない?$ rails routes | grep users# signup GET /signup(.:format) users#new POST /signup(.:format) users#create users GET /users(.:format) users#index POST /users(.:format) users#create new_user GET /users/new(.:format) users#new edit_user GET /users/:id/edit(.:format) users#edit user GET /users/:id(.:format) users#show PATCH /users/:id(.:format) users#update PUT /users/:id(.:format) users#update DELETE /users/:id(.:format) users#destroy$ rails routes | grep sessions# login GET /login(.:format) sessions#new POST /login(.:format) sessions#create logout DELETE /logout(.:format) sessions#destroy
【8.1.2 ログインフォーム 演習】
1. リスト 8.4で定義したフォームで送信すると、Sessionsコントローラのcreateアクションに到達します。Railsはこれをどうやって実現しているでしょうか? 考えてみてください。ヒント:表 8.1とリスト 8.5の1行目に注目してください。
→ routesファイルのpost '/login', to: 'sessions#create'の一文でしょう。form_forでpostリクエストを発行→ルーティングでsessionsコントローラのcreateアクションに割り当て。
【8.1.3 ユーザーの検索と認証 演習】
1. Railsコンソールを使って、表 8.2のそれぞれの式が合っているか確かめてみましょう. まずはuser = nilの場合を、次にuser = User.firstとした場合を確かめてみてください。ヒント: 必ず論理値オブジェクトとなるように、4.2.3で紹介した!!のテクニックを使ってみましょう。例: !!(user && user.authenticate('foobar'))
→ 下記>> user = nil => nil >> !!(user && user.authenticate("foobar")) => false >> user = User.first User Load (0.1ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ? [["LIMIT", 1]] => #<User id: 1, name: "Rails Tutorial", email: "example@railstutorial.org", created_at: "2020-09-12 09:09:50", updated_at: "2020-09-12 09:09:50", password_digest: "$2a$10$hrOEzw0faSd4yurmH8bQJOnggeNnUqTZg33yE9g7Tnk..."> >> !!(user && user.authenticate("matigatteruyo")) => false >> !!(user && user.authenticate("hogehoge")) => true
【8.1.5 フラッシュのテスト 演習】
1. 8.1.4の処理の流れが正しく動いているかどうか、ブラウザで確認してみてください。特に、flashがうまく機能しているかどうか、フラッシュメッセージの表示後に違うページに移動することを忘れないでください。
→ 試してみましょう。違うページに行くとフラッシュが消えます。
【8.2.1 log_in メソッド 演習】
1. 有効なユーザーで実際にログインし、ブラウザからcookiesの情報を調べてみてください。このとき、sessionの値はどうなっているでしょうか? ヒント: ブラウザでcookiesを調べる方法が分からない? 今こそググってみるときです! (コラム 1.1)
2. 先ほどの演習課題と同様に、Expiresの値について調べてみてください。
→ まとめて下の画像。Expires = 期限切れなので、緑の四角内です。ブラウザセッション終了時が有効期限になっていますね。
【8.2.2 現在のユーザー 演習】
1. Railsコンソールを使って、User.find_by(id: ...)で対応するユーザーが検索に引っかからなかったとき、nilを返すことを確認してみましょう。
→ 下記>> User.find_by(id: 8) User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 8], ["LIMIT", 1]] => nil
2. 先ほどと同様に、今度は:user_idキーを持つsessionハッシュを作成してみましょう。リスト 8.17に記したステップに従って、||=演算子がうまく動くことも確認してみましょう。
→ 下記>> session = {} => {} >> session[:user_id] = nil => nil >> @current_user ||= User.find_by(id: session[:user_id]) User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" IS NULL LIMIT ? [["LIMIT", 1]] => nil >> session[:user_id] = User.first.id User Load (0.1ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ? [["LIMIT", 1]] => 1 >> @current_user ||= User.find_by(id: session[:user_id]) User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]] => #<User id: 1, name: "Rails Tutorial", email: "example@railstutorial.org", created_at: "2020-09-12 09:09:50", updated_at: "2020-09-12 09:09:50", password_digest: "$2a$10$hrOEzw0faSd4yurmH8bQJOnggeNnUqTZg33yE9g7Tnk..."> >> @current_user ||= User.find_by(id: session[:user_id]) => #<User id: 1, name: "Rails Tutorial", email: "example@railstutorial.org", created_at: "2020-09-12 09:09:50", updated_at: "2020-09-12 09:09:50", password_digest: "$2a$10$hrOEzw0faSd4yurmH8bQJOnggeNnUqTZg33yE9g7Tnk...">
【8.2.3 レイアウトリンクを変更する 演習】
1. ブラウザのcookieインスペクタ機能を使って (8.2.1.1)、セッション用のcookieを削除してみてください。ヘッダー部分にあるリンクは非ログイン状態のものになっているでしょうか? 確認してみましょう。
→ やってみるだけ。非ログイン状態になりました。
2. もう一度ログインしてみて、ヘッダーのレイアウトが変わったことを確認してみましょう。その後、ブラウザを再起動させ、再び非ログイン状態に戻ったことも確認してみてください。注意: もしブラウザの [閉じたときの状態に戻す] 機能をオンにしていると、セッション情報も復元される可能性があります。もしその機能をオンにしている場合、忘れずにオフにしておきましょう (コラム 1.1)。
→ やってみるだけー。
【8.2.4 レイアウトの変更をテストする メモと演習】
ここのdigestメソッドのコードの書き方は正直??状態。:を2つ書くのってどういう意味なんでしょうか。前からちょくちょく出てきてるけど。調べると、PHPの記法は出てくるけど、同じような意味にとっていいのだろうか。
テストのアサーションなんかは用語集にまとめてます。1. 試しにSessionヘルパーのlogged_in?メソッドから!を削除してみて、リスト 8.23が redになることを確認してみましょう。
2. 先ほど削除した部分 (!) を元に戻して、テストが greenに戻ることを確認してみましょう。
→ まとめて。当然失敗します。ヘッダーの表示がログイン・非ログイン時で逆になっちゃうから。戻せばGREENです。
【8.2.5 ユーザー登録時にログイン メモと演習】
この章ではいろんなヘルパーメソッドを定義していますね。どこで使うために、どこに定義しているの意識しながらコードを書きましょう。コントローラで使うのか、テストで使うのか等。
1. リスト 8.25のlog_inの行をコメントアウトすると、テストスイートは red になるでしょうか? それとも green になるでしょうか? 確認してみましょう。
→ REDになります。テストにログイン状態か確かめるコード書いているので。
2. 現在使っているテキストエディタの機能を使って、リスト 8.25をまとめてコメントアウトできないか調べてみましょう。また、コメントアウトの前後でテストスイートを実行し、コメントアウトすると red に、コメントアウトを元に戻すと green になることを確認してみましょう。ヒント: コメントアウト後にファイルを保存することを忘れないようにしましょう。また、テキストエディタのコメントアウト機能については Test Editor Tutorial の Commenting Out (英語) などを参照してみてください。
→ (Macの場合)command+Aで全選択、command+/でコメントアウト。当然コメントアウトの前後でRED/GREENになります。
【8.3 ログアウト メモと演習】
1. ブラウザから [Log out] リンクをクリックし、どんな変化が起こるか確認してみましょう。また、リスト 8.31で定義した3つのステップを実行してみて、うまく動いているかどうか確認してみましょう。
→ ちゃんと動きます。
2. cookiesの内容を調べてみて、ログアウト後にはsessionが正常に削除されていることを確認してみましょう。
→ 削除されてます。
第7章まとめ
・sessionメソッドで一時的な状態保存。
・ログインではActive RecordのUserモデルを使わないので、関連づけられたエラーメッセージは使えない。
・flash.nowでrenderしたページのみフラッシュメッセージを表示。
・form_forはform_withに置き換わってるようなので参考までに。
・renderとredirect_toの使い分け。
・flashメッセージを表示。
・統合テストでログインまわりの実装を一通りテスト(ログイン/ログアウトできているか、ヘッダーは切り替わっているか)
この章は大きなエラーなく進められました。次の9章から発展的な機構を導入していきます。遂に1周しかしていない章に入っていきますね!気合入れていきましょう!
⇦ 第7章はこちら
学習にあたっての前提・著者ステータスはこちら
なんとなくイメージを掴む用語集
・ステートレス・プロトコル
状態の保持をしない独立した情報のやりとり。ログイン機能に例えると、一回ブラウザを閉じて再度入り直すと、ログインし直しになる。・セッション(session)
一連の通信のこと(ログインからログアウトまで等)。ェブサイトでは、初めて訪問した場合にブラウザのcookieに書き込まれる識別子のこと。・cookie
HTTPにおけるウェブサーバとウェブブラウザ間で状態を管理する通信プロトコル、またそこで用いられるウェブブラウザに保存された情報のこと。ECサイトの買い物カゴやログイン機能等で使われている。溜まってきたなと思ってブラウザの設定とかから消せるアレ。・assert_redirected_to
このアサーションの直前で呼び出されたリダイレクト先と、to以下のリダイレクト先が一致するかどうかテストする。・follow_redirect!
実際にそのページに移動する。移動した先で他の要素をテストする際に利用。
- 投稿日:2020-09-13T18:00:41+09:00
Rails チュートリアル バージョン違いで rails new できない時
超超初心者向けです。
railsチュートリアルで新しいアプリの作成時に
$ rails 6.0.3 new hello_app
を実行すると、
Traceback (most recent call last):
.
.
can't find gem railties (= 6.0.3) with executable rails (Gem::GemNotFoundException)このようなエラーが出てしまいました。
https://teratail.com/questions/80979
↑こちらの記事を参考にさせていただいて
$ gem install rails -v 6.0.3
でgem をインストールしてもう一度
$ rails 6.0.3 new hello_app
することで解決しました。
- 投稿日:2020-09-13T13:23:04+09:00
ruby 例外処理
この記事について
転職活動において技術課題で例外処理を記述することがあったが、これまで経験したことがなかったのでアウトプット
例外処理とは
begin #コードを指定してプログラム実行時に問題を検知させる #エラーが起こりそうなコードを記述 rescue #問題を検知した時にどのようにして対応を行わせるかを記述 end例外を発生させる
以下のようなコードだと、
100 / 0
は実行できないので、answer = 100 / number
で処理が止まってしまいます。
ZeroDivisionError
が該当のエラーであり、この例外が発生した場合に行いたい処理を記述していく。number = 0 answer = 20 / num puts answer puts 2 =>`/': divided by 0 (ZeroDivisionError) from Main.rb:4:in `<main>'例外処理
以下のように記述すると、本来であれば
100 / 0
で例外が発生するので処理が止まるところが、rescue内の処理を行うようにしているので最後まで処理が実行される。puts 1 begin #検知したいコードを記述 number = 0 answer = 20 / num puts answer rescue ZeroDivisionError => e #ZeroDivisionErrorが発生したら行いたい処理を記述(例外ハンドラを登録) p e ensure puts 2 end => 1 #<ZeroDivisionError: divided by 0> 2eとは何か?
発生した例外の詳細を格納してくれる、ZeroDivisionErrorのオブジェクト(変数)である。
つまりこれを出力すれば、なぜエラーが発生したのかが分かることができる。出力の仕方
以下のようにオブジェクトはいろいろなメッセージを持っていて、必要な情報を取り出すことができる。
p e puts e.message p e.backtrace => #<ZeroDivisionError: divided by 0> divided by 0 ["Main.rb:4:in `/'", "Main.rb:4:in `<main>'"]
- 投稿日:2020-09-13T12:00:22+09:00
【Ruby on Rails】Google API を使ったGoolgeMAPの表示とピン立て
目標
開発環境
ruby 2.5.7
Rails 5.2.4.3
OS: macOS Catalina前提
※ ▶◯◯ を選択すると、説明等が出てきますので、
よくわからない場合の参考にしていただければと思います。
- 【Ruby on Rails】郵便番号から住所を自動入力
- GoogleAPIキー発行済(GeocodingAPI MapsJavaScriptAPI)
- こちらで分かりやすく説明してくれていました
- Rails5でGoogleMapを表示してみるまで
今回は経緯緯度をGeocodingAPIを使い取得し、MAPに表示させます。
流れ
1 gemの導入
2 .envファイルを作成 <-- 1番大事です
3 viewの編集1 gemの導入
下記をGemfileに追加。
Gemfilegem "dotenv-rails"ターミナル$ bundle install
補足
dotenv-railsは.envファイルを読み込んでくれる環境変数を管理する事が出来るgemです。2 .envファイルを作成 <-- 1番大事です
Gemfileと同じ階層に .envファイルを作成
.envSECRET_KEY=自分のAPIキー # 追加する部分に <%= ENV['SECRET_KEY'] %> と入力すると使用可能).gitignoreファイルの一番下に下記を追加。
.gitignore/.env
重要
この記述を忘れてしまい、仮にGithub上に公開してしまうと、ネットに自身のAPIキーがネットに公開され、不正利用されてしまう場合があります。
もし記述し忘れで上がってしまった場合、googleに登録しているメールアドレス宛に警告メールが届くので指示に従っていただければと思います。
流れとしては、GitHubのリポジトリを削除orAPIキーの再発行(両方やるのがベストです)になるので、焦らず対処してください。3 viewの編集
表示場所はどこでもOKです。
今回は下記ページに記載。app/views/homes/mypage.html.erb<h2>Your MAP</h2> <div id='map' class="<%= current_user.prefecture_code + current_user.city + current_user.street %>"></div> <style> #map{ height: 300px; } </style> <script> let map let geocoder function initMap(){ geocoder = new google.maps.Geocoder() geocoder.geocode( { 'address': $('#map').attr('class')}, function(results, status) { if (status == 'OK') { map.setCenter(results[0].geometry.location); var marker = new google.maps.Marker({ map: map, position: results[0].geometry.location }); } else { alert('Geocode was not successful for the following reason: ' + status); } }); map = new google.maps.Map(document.getElementById('map'), { center: {lat: -35.6809591, lng: 139.7673068}, zoom: 13 }); } function codeAddress(){ let inputAddress = document.getElementById('address').value; } </script> <script src="https://maps.googleapis.com/maps/api/js?key=<%= ENV['SECRET_KEY'] %>&callback=initMap" async defer></script>下記は補足を加えたコードになります。
app/views/homes/mypage.html.erb<h2>Your MAP</h2> <!-- id=mapのclassに登録住所を代入。 --> <div id='map' class="<%= current_user.prefecture_code + current_user.city + current_user.street %>"></div> <!-- id=mapの大きさを指定。※stylesheetにまとめてもOK --> <style> #map{ height: 300px; } </style> <script> // 下記codeAddressでも使うため、mapを関数の外で定義、geocoderも用意 let map let geocoder function initMap(){ // geocoderを初期化 geocoder = new google.maps.Geocoder() // geocoderのgeocode()methodで、経緯緯度をGeocoderAPIにリクエストを送信。 // geocode()methodでaddressにid=mapのclassの登録住所を代入し、経緯緯度を取得。 geocoder.geocode( { 'address': $('#map').attr('class')}, function(results, status) { // もしエラーがなければ、 if (status == 'OK') { // map.setCenterで上記記述の経緯緯度に地図が移動。 map.setCenter(results[0].geometry.location); // google.maps.MarkerでGoogleMap上の指定位置にマーカが立つ var marker = new google.maps.Marker({ map: map, position: results[0].geometry.location }); // エラーが出た場合には } else { // statusにエラー状況が表示されるので、その文言を調べれば解決できます。 alert('Geocode was not successful for the following reason: ' + status); } }); // mapの初期位置を指定。 // latは経緯、lngは緯度。(下記は東京駅を指定しています) map = new google.maps.Map(document.getElementById('map'), { center: {lat: -35.6809591, lng: 139.7673068}, // お好みでズームサイズを変更できます。 // 数字が大きければ、拡大です。 zoom: 13 }); } function codeAddress(){ // 入力を取得 let inputAddress = document.getElementById('address').value; // geocodingしたあとmapを移動 } </script> <!-- GoogleAPIキーを読み込むための記述になります。 --> <script src="https://maps.googleapis.com/maps/api/js?key=<%= ENV['SECRET_KEY'] %>&callback=initMap" async defer></script>
- 投稿日:2020-09-13T11:42:24+09:00
【Rails】content_tagを解説してみる。
忘備録的に書いていきます。間違っている点などありましたら、コメントしていただけるとありがたいです?♂️
【概要】content_tagとは
- Railsのview helperで使われる。
- HTMLコードの要素を生成することができる。
【何が嬉しいのか?】
HTMLコードを直に書くとセキュリティ面で脆弱性が出てしまうことがある。(XSS,CSRFであったり。)
上記のようなことを防ぐために、Railsに乗っていく(
content_tag
を使う)とセキュリテイ面で恩恵を受けることができます。
HTML
とerb
がごちゃごちゃになってしまう場合に整理して書けるというメリットもあります。小さくパーシャル化するのにも使えるかもしれませんね。
【基本的な使い方】
content_tag :p, 'Hello, World!' # => <p>Hello, World!</p>第一引数にタグを指定し、第二引数に
content
となる部分を埋め込む。ちなみに、第二引数にはシンボル(
:p
みたいな)だけではなく、文字列も許容してくれるcontent_tag 'p', 'Hello, World!' # => <p>Hello, World!</p>少し、実践的な書き方をするとこんな感じ???
content_tag :p, @user.name # => <p>佐藤</p>「こんなこともできるよ」集
HTMLオプションはハッシュで
content_tag :p 'Hello' class: 'hoge' # => <p class='hoge'>Hello</p>こんな感じで
class
を持たせることもできます。ちなみに、複数のclass
を持たせるには下記のように書けばOKcontent_tag(:p, 'Hello', class: ["hoge", "foo"]) # => <div class="hoge foo">Hello</div>ネストもできるよ
content_tag :div do content_tag :p @user.name content_tag :p @user.age endこんな感じにネストして書くこともできる。
おいおい、#tagって知ってるか??
下記はみんな大好きDHHのissueです。
https://github.com/rails/rails/issues/25195
content_tag :span, nil, class: 'bookmark' # 下記は上記と同じ意味 tag.span class: 'bookmark'すごい直感的に書けるようになりましたよね。
色々変わったのですが、個人的には下記がお気に入り。
tag.div(id: 'header') { |tag| tag.span 'hello' } # <div id="header"><span>hello</span></div>でも、下記も簡潔に書けますよね。
<%= tag.p do %> hoge <% end %>特に理由がなれば、
content_tag
ではなく、tag
を使うと可読性が上がるかな〜と思いました。参考関連記事
https://qiita.com/ren0826jam/items/0ebd451d1da90e496c2f
https://makicamel.hatenablog.com/entry/2019/03/07/224552
https://techracho.bpsinc.jp/hachi8833/2018_11_01/48191
- 投稿日:2020-09-13T10:01:17+09:00
Rails 6で認証認可入り掲示板APIを構築する #8 seed実装
←Rails 6で認証認可入り掲示板APIを構築する #7 update, destroy実装
seedとは
開発中にテストデータが必要な時、都度
rails c
やらcreate actionを叩いてレコード作るのは手間です。
そこで、コマンドを叩くだけであらかじめ設定しておいたレコードを、50だろうが1000だろうが簡単に作れるseedを取り入れます。ファイル作成とロード
rails seedだけでググると大抵db/seeds.rbに直書きばかり出てきますが、modelが多くなると管理がしづらくなります。
そこでファイルを分割し、db/seeds.rbからrequireで呼ぶ形式にします。こうすることで追加削除時の管理がしやすくなりますし、seedはファイル指定で実行することもできるので便利です。
$ mkdir db/seeds $ touch db/seeds/post_seeds.rbdb/seeds.rb# frozen_string_literal: true seed_models = %i[post] seed_models.each do |model| require "./db/seeds/#{model}_seeds" enddb/seeds/post_seeds.rb# frozen_string_literal: true unless Post.exists? 20.times do Post.create!(subject: "hoge", body: "fuga") end end今後seed対象のmodelが増えることを予想し、seed_modelsという変数に追加していくことで外部ファイル読み込みをするようにします。
ディレクトリ走査することで都度db/seeds.rbを変更しなくても良い作りにできるのですが、postモデルの前に今後作るuserモデルのレコードが存在していないといけない等の依存関係が発生するので、手動で実行順を弄れるように書いています。post_seeds.rbの中身は単純に
Post.create!
を20回実行しているだけです。
!
を付けることによりバリデーションエラーで登録できなかった際に例外が投げられるので、気付いたらレコードが生成されていなかった事態を防げます。$ rails db:reset $ rails db:seed $ rails c [1] pry(main)> Post.count (1.1ms) SELECT COUNT(*) FROM "posts" => 20db:resetすることでテーブルを全dropし再生成。これでレコードがある時のみ動くseedが実行されます。
そしてdb:seedすることで、20レコードが追加されていることが確認できます。Fakerの導入
レコードができたのはいいのですが全部subjectがhoge, bodyがfugaになっています。
このままだと、何かしらの原因でAPIから取得したら同一レコードが紛れていたりしても気付きづらくなります。
とはいえ完全ランダムな文字列を都度作るのも手間だし…ということで、役立つのがFakerです。とりあえず入れてみましょう。
Gemfile... group :development, :test do ... + "faker" end ...$ bundle試しに使ってみましょう。
$ rails c [1] pry(main)> Faker::Name.unique.name => "Miss Porter Kovacek" [2] pry(main)> Faker::Name.name => "Felicita Durgan" [3] pry(main)> Faker::Name.name => "Yong Weissnat" [4] pry(main)> Faker::Name.name => "Sandie Oberbrunner"こんな感じに、実行のたびにランダムな名詞や文章を自動で返してくれるものです。
デフォルトで定義されている語句はGithubで確認すると良いです。
人名や動物、住所や電話番号等だけでなく、映画、漫画、ゲーム、ドラマ、音楽なんかもあります。ポケモン名とかONE PIECEの悪魔の実とかまでありますね。seedsにFakerを入れる
db/seeds/post_seeds.rb# frozen_string_literal: true unless Post.exists? 20.times do - Post.create!(subject: "hoge", body: "fuga") + Post.create!(subject: Faker::Lorem.word, body: Faker::Lorem.paragraph) end end$ db:reset $ db:seed $ rails c [1] pry(main)> Post.all Post Load (0.4ms) SELECT "posts".* FROM "posts" => [#<Post:0x000000000636cbe8 id: 1, subject: "quos", body: "Earum numquam qui. Impedit autem molestias. Ipsum adipisci eos.", created_at: Sun, 06 Sep 2020 15:36:27 UTC +00:00, updated_at: Sun, 06 Sep 2020 15:36:27 UTC +00:00>, #<Post:0x00000000063b5be0 id: 2, subject: "vero", body: "Impedit distinctio saepe. Adipisci cupiditate officiis. Vel et deleniti.", created_at: Sun, 06 Sep 2020 15:36:27 UTC +00:00, updated_at: Sun, 06 Sep 2020 15:36:27 UTC +00:00>,ランダムなsubject, bodyのレコードができていることが確認できます。
Fakerを日本語化する
せっかく入れたのに英語だと日本語サイトを作る上で不便なので、ローカライズしましょう。
db:seedはdev環境で実行するので、dev環境の時にFakerを日本語化してみます。config/environments/development.rbRails.application.configure do ... + Faker::Config.locale = "ja" end常に日本語化が嫌なのであれば、
Faker::Config.locale = "ja"
をdb/seeds/post_seeds.rbに入れてもOKです。
その後再度seedを実行します。$ rails db:reset $ rails db:seed $ rails c [1] pry(main)> Post.all Post Load (0.3ms) SELECT "posts".* FROM "posts" => [#<Post:0x0000000006480b88 id: 1, subject: "いく", body: "警官総括大尉。めいしぼきんかたみち。伝統徳川超〜。", created_at: Sun, 06 Sep 2020 15:45:27 UTC +00:00, updated_at: Sun, 06 Sep 2020 15:45:27 UTC +00:00>, #<Post:0x00000000064fb928 id: 2, subject: "フランス語", body: "〜系けいかん先週。うえる自宅そだてる。店舗にんい高値。", created_at: Sun, 06 Sep 2020 15:45:27 UTC +00:00, updated_at: Sun, 06 Sep 2020 15:45:27 UTC +00:00>,無事に日本語化されていますね。
なお、日本語化されているものはGithubで確認できます。逆に言えばこの中に無いものは英語のままです。続き
- 投稿日:2020-09-13T06:20:48+09:00
Rails uninitialized constant エラーの解決へのシンプルなチェックリスト
これはなにか
Railsをそれなりにやっているにも関わらず、uninitialized constant error にハマってしまったのでチェックリストをここにまとめておこうと思う。
結論
チェックするべき項目は以下3点である。
- ファイル名とclass名が一致しているか?
- ファイルpathとmoduleの定義が一致しているか?
- Railsにファイルを読み込ませているか?
以下詳細をかいていく。
ファイル名とclass名が一致しているか?
以下のようなclassが存在していたら、ファイル名は
qiita_user.rb
でないといけない。class QiitaUser def hoge end endファイルpathとmoduleの定義が一致しているか?
以下のようなmoduleにnestされたclassが存在していたら、pathは
**/v1/auth/user.rb
のようになるだろう。class V1::Auth::User endOR
module V1 module Auth class User end end endRailsにファイルを読み込ませているか?
Railsのデフォルトのフォルダ以外に、フォルダを追加する場合、autoload pathに追加したフォルダへのpathを定義する必要がある。
app/lib/hoge/foo.rb
を追加したとする。この場合、config/application.rb
に以下の様な形で、autoload pathを追加する必要がある。module App class Application < Rails::Application # 省略 config.autoload_paths += Dir.glob("#{config.root}/app/lib") end end
- 投稿日:2020-09-13T02:03:49+09:00
slimの長い構文を途中で改行する
Railsアプリ開発時にslimを使ってhtmlを書いているときに、このような長い構文がある。これを改行する方法。
.card-toolbar a.btn.btn-primary.status-editable data-confirm="全ユーザーの編集権限を「編集可」に変更します。よろしいですか?" style="font-size: 15px; margin: 0 10px;" href="#{toggle_status_editable_admins_supplier_company_path(supplier_company_code: model.code, supplier_company_id: model.id)}" role="button" 編集可 a.btn.btn-danger.status-editable data-confirm="全ユーザーの編集権限を「編集可」に変更します。よろしいですか?" style="font-size: 15px; margin: 0 10px;" href="#{toggle_status_not_editable_admins_supplier_company_path(supplier_company_code: model.code, supplier_company_id: model.id)}" role="button" 編集不可こんな感じで[]をつけて改行できる。
.card-toolbar a[data-confirm="全ユーザーの編集権限を「編集可」に変更します。よろしいですか?" style="font-size: 15px; margin: 0 10px;" href="#{toggle_status_editable_admins_supplier_company_path(supplier_company_code: model.code, supplier_company_id: model.id)}" role="button"] .btn.btn-primary.status-editable | 編集可 a[data-confirm="全ユーザーの編集権限を「編集不可」に変更します。よろしいですか?" style="font-size: 15px; margin: 0 10px;" href="#{toggle_status_not_editable_admins_supplier_company_path(supplier_company_code: model.code, supplier_company_id: model.id)}" role="button"] .btn.btn-danger.status-editable | 編集不可
- 投稿日:2020-09-13T02:00:46+09:00
[Rails]外部キー制限かかっているときにdestoryできないエラーを発生させたい時の対処
はじめに
レコード削除時に関連づけられたレコードが存在するときに、例外やエラーを発生させたい。
外部キーで使用されていると親要素が消されては困るというシチュエーションです。削除しようとするとRubyのエラー画面が出てしまう。
原因
Model
に関係づけされたモデルに対する挙動を定義するが無いからでした。
マイグレーションファイルのforeign key: True
だけでは不十分でした。対策
Model
にdependentオプション
を記述することで解決しました。
該当のモデルに以下の記述をします。#contractというモデル class Contract < ApplicationRecord has_many :...., dependent: :restrict_with_error endアソシエーション記述の後に
dependent: :restrict_with_error
と記述することでdestory
できないときのエラーを表示することができた。
以下の条件分が成り立ち解決しました!。#contractというモデルのコントローラー def destroy contract = Contract.find(params[:id]) if contract.destroy redirect_to contract_path, notice: "選んだ契約を削除しました" else redirect_to contract_path, alert: "使用中のため削除できません" end end参照
・https://dorarep.page/articles/rails-dependent#dependent_restrict_with_exception_restrict_with_error
- 投稿日:2020-09-13T01:42:37+09:00
[Rails]errorsメソッドでメッセージ表示させるとビューが崩れる時の対処
はじめに
form
で入力に誤り(例えば無入力)があるとエラーメッセージを表示させるためにerrorsメソッド
を用いて記述し、動きを確認するとビューが崩れるという問題が発生しました。その時の自分の解決した方法です。原因
崩れたビューを確認すると
field_with_errors
というdivクラス
が付与させていていることを確認した。これが原因である。対処
今回はこの
field_with_errors
というdivクラス
が付与されないようにした。
config/application.rb
に以下の記述をした。module #モデル名 class Application < Rails::Application config.load_defaults 6.0 config.i18n.default_locale = :ja config.action_view.field_error_proc = Proc.new { |html_tag, instance| html_tag } #↑この記述をプラスした end endこうすることで余計なクラスが付与されずにできました!
参考
- 投稿日:2020-09-13T01:29:25+09:00
[Rails]errorsメソッドでエラーメッセージが出せないときの対処
はじめに
例えば
result.save
のように変数result
の保存をしようとした時に、失敗するとresultにエラーメッセージが格納される。
これを利用してエラーメッセージを表示させたいがRubyのエラー画面となる。言い換えると思い通りのエラーメッセージが出ない。
エラー時にコンソールで確認の以下のようになる
result.errors.any? => False保存できてないのにエラー出てないことになってる。
今回は無入力で登録しようとするとエラーを出したい。
原因
Model
にバリデーション記述が無かったことが原因。
テーブル作成時にはカラムに制限(無入力制限のためnull: false
とした)がそれだけではエラーメッセージがでない。対策
Model
に以下のような記述をした。class Result < ApplicationRecord belongs_to ... has_many ... validates :name, presence: true ... end
validates :name, presence: true
と記述することでresult.errors.any? => Trueとなり
result.errors.full_messagesで、エラーメッセージ全件の内容を取得し
each
を用いて取り出せました!