- 投稿日:2020-04-06T23:48:40+09:00
【Rails】whenever によるバッチ処理(runner編)
はじめに
whenever が使いやすいと書かれていたにもかかわらず、少しはまってしまったのでまとめます。
特に、runner について書きたいと思います。GemFile
GemFile に whenever を追記して
bundle install
GemFilegem 'whenever', :require => false$ bundle install自動化したいソースを記述
と、その前に準備があります。
config/application.rb に 以下の1行を追記してください。
lib のディレクトリの内容を反映させるようです。ここがはまってしまったポイントです。
config/application.rbclass Application < Rails::Application # 追記 config.autoload_paths += Dir["#{config.root}/lib"] endlib/batch/hoge.rb に自動化したいソースを記述してください。
lib/batch/hoge.rbclass Batch::Hoge def self.hoge puts "Hoge!" end endターミナル上で実行できるかどうかを確認。
$ bundle exec rails runner Batch::Hoge.hoge => "Hoge!"自動化のスケジュールを作成
下記コマンドを実行することで、config/schedule.rb を作成。
$ bundle exec wheneverize .config/schedule.rb に、下記を記載。
自動化させたい頻度と実行したいメソッドを指定してください。config/schedule.rbset :output, 'log/crontab.log' set :environment, :development set :runner_command, "rails runner" every 1.day, at: '9:00 am' do runner "Batch::ManHoursToBacklog.send_backlog" end作成した自動化ソースをcronへ反映・確認・削除
# cron への反映 $ bundle exec whenever --update-crontab# cron へ反映した内容の確認(どちらの行でも確認できる) $ bundle exec whenever $ bundle exec crontab -e# cron へ反映した内容を削除 $ bundle exec whenever --clear-crontabまとめ
以上が whenever を使ったバッチ処理反映方法でした。
少しでも参考になる方がいれば嬉しいです。参考
- Railsで定期的にバッチ回す「Whenever」
- Rails runnerを使ってファイルを実行しました
- javan/whenever (GitHub)
- dignoe/whenever-elasticbeanstalk (GitHub)
- 投稿日:2020-04-06T22:59:04+09:00
【Ruby】【短期】Qiitaの読んでおかなければいけない記事100選【毎日自動更新】
ページ容量を増やさないために、不具合報告やコメントは、説明記事 に記載いただけると助かります。
順位 記事名
________________________________________ユーザ 投稿日付
更新日付LGTM1 1 (下準備編)世界一丁寧なAWS解説。EC2を利用して、RailsアプリをAWSにあげるまで naoki_mochizuki 16/01/08
19/01/172591
1662 プログラミング勉強を加速させる7つの習慣 YudaiTsukamoto 16/12/15
16/12/212933
693 高校文化祭の食販で自動注文機を作った話 RyotaroSaito 19/11/15
19/12/221304
104 一番詳しいCSS設計規則BEMのマニュアル Takuan_Oishii 17/08/30
19/07/16787
1535 【初心者向け】丁寧すぎるRails『アソシエーション』チュートリアル【幾ら何でも】【完璧にわかる】? kazukimatsumoto 18/11/29
19/12/06711
1626 未経験からRuby on Railsを学んで仕事につなげるまでの1000時間メニュー saboyutaka 18/12/09
19/09/141178
557 【初心者向け】テストコードの方針を考える(何をテストすべきか?どんなテストを書くべきか?) jnchito 18/05/22
18/06/141173
758 使えるRSpec入門・その1「RSpecの基本的な構文や便利な機能を理解する」 jnchito 14/10/26
19/07/222924
09 【まつもとゆきひろ氏 特別講演】20代エンジニアのためのプログラマー勉強法のまとめ 2019/3/30 motoki4917 19/03/30
19/10/191642
3110 [Rails] deviseの使い方(rails5版) cigalecigales 16/11/13
18/05/17852
5911 非デザイナーエンジニアが一人でWebサービスを作るときに便利なツール32選 okappy 14/09/18
15/07/086312
012 Railsアプリケーションにおけるエラー処理(例外設計)の考え方 jnchito 15/09/28
20/02/031557
6813 Rails deviseで使えるようになるヘルパーメソッド一覧 tobita0000 17/05/07
17/05/07488
6214 Railsで超簡単API k-penguin-sato 18/06/27
20/02/24387
5915 Rails開発におけるwebサーバーとアプリケーションサーバーの違い(翻訳) jnchito 15/10/20
15/10/211223
3516 削除済(ID:b1aa2ae143624e551aea) saitoeku3 18/06/18
19/07/05299
5517 Rails5.2から追加された credentials.yml.enc のキホン NaokiIshimura 18/04/12
18/04/13413
4418 Rails における内部結合、外部結合まとめ yuyasat 16/09/03
19/01/14574
4519 プログラミング初心者歓迎!「エラーが出ました。どうすればいいですか?」から卒業するための基本と極意(解説動画付き) jnchito 16/06/26
19/05/011167
4220 なぜrailsの本番環境ではUnicorn,Nginxを使うのか? ~ Rack,Unicorn,Nginxの連携について ~【Ruby On Railsでwebサービス運営】 takahiro1127 18/05/13
19/11/13268
7421 「アプリケーションが壊れているのに検知できないテストコード」を書かないようにするための、べからず集 jnchito 20/01/29
20/02/09528
52822 (デプロイ編①)世界一丁寧なAWS解説。EC2を利用して、RailsアプリをAWSにあげるまで naoki_mochizuki 16/01/12
20/01/17569
5223 【これが無料?】無料で学べるプログラミング教材・ハンズオン一覧 kocpa 19/06/26
19/07/05935
924 【Rails 5】(新) form_with と (旧) form_tag, form_for の違い hmmrjn 18/07/01
18/07/03392
4225 rails generate migrationコマンドまとめ zaru 14/09/09
18/11/061467
026 Ruby on Rails, Vue.js で始めるモダン WEB アプリケーション入門 tatsurou313 19/02/11
19/09/29273
6527 [初心者向け] RubyやRailsでリファクタリングに使えそうなイディオムとか便利メソッドとか jnchito 13/11/04
18/03/143008
028 未経験者には全てが黒魔術に見える呪いがある mackey0022 19/10/15
19/10/18471
2229 「Railsは終わった」と言われる理由 klriutsa 19/03/05
19/08/22432
5530 【Rails 5.2】 Active Storageの使い方 hmmrjn 18/06/30
19/08/06338
4231 VSCodeでRuby On Railsを快適に書きたい sensuikan1973 18/10/07
19/06/17479
3632 【爆速成長!】プログラミング駆け出し〜オリジナルポートフォリオ作成までに参考にしたサイト一覧 taku99 20/03/27
20/03/27308
30833 【Rails】MySQL2がbundle installできない時の対応方法 fukuda_fu 19/03/21
19/04/10238
5834 【サーバーサイド一式】Docker + Rails + Circle CI + Terraformでインフラをコードで環境構築 & ECSへ自動コンテナデプロイ【前半】 kazukimatsumoto 19/12/04
19/12/16526
5335 Railsバリデーションまとめ shunhikita 15/02/24
17/11/151037
036 Rubyによるデザインパターンまとめ yuji_ariyasu 18/09/10
19/08/15525
3337 Ruby on Rails カラムの追加と削除 azusanakano 16/03/29
16/03/29310
4338 [Docker] 初心者が知っておくと便利かもしれない18の知識 enta0701 17/09/30
19/01/17376
2939 gem installでpermissionエラーになった時の対応方法 nishina555 18/11/25
19/09/25220
5340 スタブとモックの違い k5trismegistus 17/04/05
17/04/06361
3341 Ruby on Rails 6の主要な新機能・機能追加・変更点 ryohashimoto 18/12/22
19/10/21291
3842 【初心者向け】RailsのActive Recordの解説&メソッドまとめ ryokky59 18/10/05
18/10/05184
5043 bundle install と bundle updateの違いについて lasershow 16/01/21
16/01/21370
3044 決定版!!Haml小技まとめ!! yukimura1227 16/04/16
18/11/29293
3445 find、find_by、whereの違い tsuchinoko_run 18/03/17
18/03/17216
5046 mysql2 gemインストール時のトラブルシュート HrsUed 18/11/28
19/04/16264
2447 ActiveRecordのjoinsとpreloadとincludesとeager_loadの違い k0kubun 14/09/04
16/02/111507
048 Rubyの文字列とシンボルの違いをキッチリ説明できる人になりたい Kta-M 16/09/05
19/04/07441
2749 Railsアプリで Bootstrap 4 を利用する NaokiIshimura 17/11/03
19/08/14292
3350 bundle install時に--path vendor/bundleを付ける必要性は本当にあるのか、もう一度よく考えてみよう jnchito 19/06/06
19/06/07304
5051 Rails で includes して N+1 問題対策 hirotakasasaki 17/02/10
17/02/11321
3152 [Ruby入門] 14. 日付と時刻を扱う(全パターン網羅) prgseek 17/04/28
17/05/05289
3553 Capybaraチートシート morrr 17/08/19
17/08/19289
2454 RailsアプリをDockerで開発するための手順 togana 16/04/11
17/07/31684
2555 railsのrenderとredirect_toの違い 1ulce 16/12/02
16/12/02310
1956 【Rails初心者必見!】ひたすら丁寧にデータ取得を説明(find, where) mr-myself 15/09/03
15/09/03435
3757 [Rails]ransackを利用した色々な検索フォーム作成方法まとめ nishina555 17/03/02
19/05/13294
2958 (DB・サーバー構築編)世界一丁寧なAWS解説。EC2を利用して、RailsアプリをAWSにあげるまで naoki_mochizuki 16/01/10
19/01/17459
3359 bundle install 時、mysql2でエラー tktcorporation 18/12/26
19/07/25227
2860 【まつもとゆきひろ氏 特別講演】若手エンジニアの生存戦略に行ってきたので私的メモ DAdDY0055 18/06/23
18/06/271244
361 あなたはいくつ知っている?Rails I18nの便利機能大全! Kta-M 17/06/26
19/04/19350
2662 並行処理、並列処理のあれこれ Kohei909Otsuka 18/02/14
18/02/15215
3163 【Rails】deviseを導入してみる Hal_mai 18/11/07
18/11/08161
4264 rspec-rails 3.7の新機能!System Specを使ってみた jnchito 17/10/23
19/12/14362
2365 Awesome Ruby : 素晴しい Ruby のライブラリ・ツール・フレームワーク・ソフトウェアの数々 hatai 17/07/24
19/11/01550
1566 Railsのjbuilderの書き方と便利なイディオムやメソッド ryouzi 17/11/28
19/01/08274
2467 忘れがちなrenderメソッドの使い方まとめ [Rails] hayashino 18/11/24
18/12/01140
5468 Rails の session を完全に理解した zettaittenani 18/12/17
19/07/16184
3169 Bundlerの使い方 oshou 16/03/27
17/02/03387
2070 N+1問題 TsubasaTakagi 17/12/07
17/12/07188
3271 モデルやメソッドに名前を付けるときは英語の品詞に気をつけよう jnchito 14/05/28
17/06/273076
072 Ruby on Rails+ReactでCRUDを実装してみた yoshimo123 18/02/17
19/02/28240
2673 Railsのポリモーフィック関連とはなんなのか itkrt2y 16/12/03
18/12/20310
2874 【2018年版】macにrbenvを入れてrubyを管理できるようにしちゃう Alex_mht_code 18/04/17
19/06/07236
2175 RubyとRailsにおけるTime, Date, DateTime, TimeWithZoneの違い jnchito 14/12/07
18/01/251425
076 Rails 5.2 で ActiveSupport::MessageEncryptor::InvalidMessage scivola 18/05/24
19/05/27230
2877 Webpacker使うなら最低限これだけは知っておいてほしいこと chimame 18/08/07
19/12/18207
2878 使えるRSpec入門・その2「使用頻度の高いマッチャを使いこなす」 jnchito 14/11/05
19/07/22941
079 みんなRailsのSTIを誤解してないか!? yebihara 16/12/04
16/12/16429
2980 ニコニ立体を直した話 uproad3 19/11/07
19/12/02230
081 Docker + Rails + Puma + Nginx + MySQL eighty8 17/08/25
19/10/28174
3582 あなたはDRY原則を誤認している? yatmsu 16/12/06
18/07/29236
2583 使えるRSpec入門・その4「どんなブラウザ操作も自由自在!逆引きCapybara大辞典」 jnchito 15/01/01
19/07/221096
084 Ruby 正規表現の使い方 shizuma 15/07/27
15/07/28485
2585 VSCode公式の機能で、リモートサーバにSSHして編集する【Insiders Preview】 suzuki_sh 19/05/03
19/05/12372
1886 永久保存版!?伊藤さん式・Railsアプリのアップグレード手順 jnchito 19/08/18
19/10/24337
3787 はじめてのRails API c5meru 17/12/16
17/12/16296
1888 20万pv/月達成のwebサービスのRailsソースコード、全部見せます! kent_ear 18/07/31
19/08/22788
789 AWS:無料でSSL証明書を取得する方法 iwaseasahi 17/06/03
18/01/13255
2190 フロントエンド全然わからないマンが、ちょっとでも見た目のいいWebサービスを作ろうとしてやったこと liukoki 18/03/21
18/03/251018
1591 RubyのModuleの使い方とはいったい shiopon01 16/09/15
16/09/15264
2592 Rails enumについてまとめておく shizuma 16/01/07
16/01/07275
2393 redirect_to @userが何を省略しているかわかりますか?〜挫折しないRailsチュートリアル7章〜 Kawanji01 18/07/05
20/03/16168
4394 実務で学んだRailsの設計・リファクタリング wawoon 17/12/08
19/02/10203
2795 あなたがマスターしたのはいくつ? Railsを習得するために必要な技術要素の一覧 jnchito 16/07/06
16/07/261175
1796 railsで多対多のアソシエーションの作り方と、出来ること Kohei_Kishimoto0214 17/01/19
17/06/26286
1897 RailsアプリへのRspecとFactory_botの導入手順 Ushinji 18/01/08
19/12/14208
2398 [初学者]Railsのi18nによる日本語化対応 shimadama 18/07/31
20/03/22153
3599 docker-composeを爆速にする shotat 18/05/13
18/05/13174
46100 Railsのルーティングの種類と要点まとめ senou 16/05/20
19/02/05229
24
1行目が総数。2行目が直近3ヵ月。 ↩
- 投稿日:2020-04-06T22:58:54+09:00
【Ruby】【長期】Qiitaの読んでおかなければいけない記事100選【毎日自動更新】
ページ容量を増やさないために、不具合報告やコメントは、説明記事 に記載いただけると助かります。
順位 記事名
________________________________________ユーザ 投稿日付
更新日付LGTM1 1 (下準備編)世界一丁寧なAWS解説。EC2を利用して、RailsアプリをAWSにあげるまで naoki_mochizuki 16/01/08
19/01/172591
9132 プログラミング勉強を加速させる7つの習慣 YudaiTsukamoto 16/12/15
16/12/212933
4713 使えるRSpec入門・その1「RSpecの基本的な構文や便利な機能を理解する」 jnchito 14/10/26
19/07/222924
3434 非デザイナーエンジニアが一人でWebサービスを作るときに便利なツール32選 okappy 14/09/18
15/07/086312
3085 一番詳しいCSS設計規則BEMのマニュアル Takuan_Oishii 17/08/30
19/07/16787
5606 [初心者向け] RubyやRailsでリファクタリングに使えそうなイディオムとか便利メソッドとか jnchito 13/11/04
18/03/143008
1897 rails generate migrationコマンドまとめ zaru 14/09/09
18/11/061467
2168 【初心者向け】丁寧すぎるRails『アソシエーション』チュートリアル【幾ら何でも】【完璧にわかる】? kazukimatsumoto 18/11/29
19/12/06711
5119 [Rails] deviseの使い方(rails5版) cigalecigales 16/11/13
18/05/17852
25410 未経験からRuby on Railsを学んで仕事につなげるまでの1000時間メニュー saboyutaka 18/12/09
19/09/141178
48811 Railsアプリケーションにおけるエラー処理(例外設計)の考え方 jnchito 15/09/28
20/02/031557
24212 Rails開発におけるwebサーバーとアプリケーションサーバーの違い(翻訳) jnchito 15/10/20
15/10/211223
20313 【初心者向け】テストコードの方針を考える(何をテストすべきか?どんなテストを書くべきか?) jnchito 18/05/22
18/06/141173
31914 Railsバリデーションまとめ shunhikita 15/02/24
17/11/151037
19515 高校文化祭の食販で自動注文機を作った話 RyotaroSaito 19/11/15
19/12/221304
130416 【まつもとゆきひろ氏 特別講演】20代エンジニアのためのプログラマー勉強法のまとめ 2019/3/30 motoki4917 19/03/30
19/10/191642
46217 Rails deviseで使えるようになるヘルパーメソッド一覧 tobita0000 17/05/07
17/05/07488
27418 プログラミング初心者歓迎!「エラーが出ました。どうすればいいですか?」から卒業するための基本と極意(解説動画付き) jnchito 16/06/26
19/05/011167
21819 ActiveRecordのjoinsとpreloadとincludesとeager_loadの違い k0kubun 14/09/04
16/02/111507
14920 Rails における内部結合、外部結合まとめ yuyasat 16/09/03
19/01/14574
20421 (デプロイ編①)世界一丁寧なAWS解説。EC2を利用して、RailsアプリをAWSにあげるまで naoki_mochizuki 16/01/12
20/01/17569
20322 モデルやメソッドに名前を付けるときは英語の品詞に気をつけよう jnchito 14/05/28
17/06/273076
11923 Railsで超簡単API k-penguin-sato 18/06/27
20/02/24387
32424 RubyとRailsにおけるTime, Date, DateTime, TimeWithZoneの違い jnchito 14/12/07
18/01/251425
11825 使えるRSpec入門・その2「使用頻度の高いマッチャを使いこなす」 jnchito 14/11/05
19/07/22941
14026 使えるRSpec入門・その4「どんなブラウザ操作も自由自在!逆引きCapybara大辞典」 jnchito 15/01/01
19/07/221096
12727 Rails5.2から追加された credentials.yml.enc のキホン NaokiIshimura 18/04/12
18/04/13413
23628 脱初心者を目指すVimmerにオススメしたいVimプラグインや.vimrcの設定 jnchito 14/06/08
18/05/151938
8229 RailsアプリをDockerで開発するための手順 togana 16/04/11
17/07/31684
8830 Ruby on Rails カラムの追加と削除 azusanakano 16/03/29
16/03/29310
16331 【Rails 5】(新) form_with と (旧) form_tag, form_for の違い hmmrjn 18/07/01
18/07/03392
23932 bundle install と bundle updateの違いについて lasershow 16/01/21
16/01/21370
14333 スタブとモックの違い k5trismegistus 17/04/05
17/04/06361
16534 削除済(ID:b1aa2ae143624e551aea) saitoeku3 18/06/18
19/07/05299
26035 Rubyの文字列とシンボルの違いをキッチリ説明できる人になりたい Kta-M 16/09/05
19/04/07441
13636 【Rails初心者必見!】ひたすら丁寧にデータ取得を説明(find, where) mr-myself 15/09/03
15/09/03435
12137 【Rails 5.2】 Active Storageの使い方 hmmrjn 18/06/30
19/08/06338
21838 [Docker] 初心者が知っておくと便利かもしれない18の知識 enta0701 17/09/30
19/01/17376
19739 使えるRSpec入門・その3「ゼロからわかるモック(mock)を使ったテストの書き方」 jnchito 14/11/21
15/09/29969
10940 VSCodeでRuby On Railsを快適に書きたい sensuikan1973 18/10/07
19/06/17479
22541 なぜrailsの本番環境ではUnicorn,Nginxを使うのか? ~ Rack,Unicorn,Nginxの連携について ~【Ruby On Railsでwebサービス運営】 takahiro1127 18/05/13
19/11/13268
23442 決定版!!Haml小技まとめ!! yukimura1227 16/04/16
18/11/29293
15643 【これが無料?】無料で学べるプログラミング教材・ハンズオン一覧 kocpa 19/06/26
19/07/05935
93544 Rubyで%記法(パーセント記法)を使う mogulla3 14/08/23
14/08/23903
8645 Bundlerの使い方 oshou 16/03/27
17/02/03387
12146 「Railsは終わった」と言われる理由 klriutsa 19/03/05
19/08/22432
28047 railsのrenderとredirect_toの違い 1ulce 16/12/02
16/12/02310
15048 (DB・サーバー構築編)世界一丁寧なAWS解説。EC2を利用して、RailsアプリをAWSにあげるまで naoki_mochizuki 16/01/10
19/01/17459
13649 nil? empty? blank? present? の使い分け somewhatgood@github 13/01/24
13/01/241084
10050 Rails で includes して N+1 問題対策 hirotakasasaki 17/02/10
17/02/11321
12951 Ruby on Rails, Vue.js で始めるモダン WEB アプリケーション入門 tatsurou313 19/02/11
19/09/29273
26652 Awesome Ruby : 素晴しい Ruby のライブラリ・ツール・フレームワーク・ソフトウェアの数々 hatai 17/07/24
19/11/01550
11053 Rubyによるデザインパターンまとめ yuji_ariyasu 18/09/10
19/08/15525
17054 [Rails]ransackを利用した色々な検索フォーム作成方法まとめ nishina555 17/03/02
19/05/13294
14455 [Ruby入門] 14. 日付と時刻を扱う(全パターン網羅) prgseek 17/04/28
17/05/05289
14656 早く知ってたら良かったrailsの技 k-shogo 14/12/18
14/12/181125
7557 Ruby 正規表現の使い方 shizuma 15/07/27
15/07/28485
11758 Capybaraチートシート morrr 17/08/19
17/08/19289
14559 Railsアプリで Bootstrap 4 を利用する NaokiIshimura 17/11/03
19/08/14292
14660 あなたがマスターしたのはいくつ? Railsを習得するために必要な技術要素の一覧 jnchito 16/07/06
16/07/261175
9861 【Rails】form_for/form_tagの違い・使い分けをまとめた shunsuke227ono 15/04/28
16/11/15834
7162 Ruby block/proc/lambdaの使いどころ kidach1 13/11/18
17/01/291427
8363 あなたはいくつ知っている?Rails I18nの便利機能大全! Kta-M 17/06/26
19/04/19350
12764 知識0から、AWSのEC2でウェブサーバーを構築するまで shunsuke227ono 15/10/26
16/04/24461
9765 Railsのポリモーフィック関連とはなんなのか itkrt2y 16/12/03
18/12/20310
10466 中規模Web開発のためのMVC分割とレイヤアーキテクチャ yuku_t 14/05/20
17/08/151725
6767 みんなRailsのSTIを誤解してないか!? yebihara 16/12/04
16/12/16429
10168 【まつもとゆきひろ氏 特別講演】若手エンジニアの生存戦略に行ってきたので私的メモ DAdDY0055 18/06/23
18/06/271244
1069 Rails enumについてまとめておく shizuma 16/01/07
16/01/07275
10670 【初心者向け】これからRailsエンジニアとして成長したい人がすべきこと hc0208 16/03/21
18/10/15356
10371 Ruby on Rails 6の主要な新機能・機能追加・変更点 ryohashimoto 18/12/22
19/10/21291
21772 【Rails】MySQL2がbundle installできない時の対応方法 fukuda_fu 19/03/21
19/04/10238
23673 俺が悪かった。素直に間違いを認めるから、もうサービスクラスとか作るのは止めてくれ joker1007 16/12/15
17/01/08945
8474 RubyのModuleの使い方とはいったい shiopon01 16/09/15
16/09/15264
10775 rspec-rails 3.7の新機能!System Specを使ってみた jnchito 17/10/23
19/12/14362
13776 Railsのjbuilderの書き方と便利なイディオムやメソッド ryouzi 17/11/28
19/01/08274
13977 railsで多対多のアソシエーションの作り方と、出来ること Kohei_Kishimoto0214 17/01/19
17/06/26286
10378 gem installでpermissionエラーになった時の対応方法 nishina555 18/11/25
19/09/25220
20279 ノンプログラマーが3ヶ月でWebサービスを作ってみた tabbyz 15/02/25
16/03/271597
5680 あなたはDRY原則を誤認している? yatmsu 16/12/06
18/07/29236
11081 Railsのルーティングの種類と要点まとめ senou 16/05/20
19/02/05229
10382 mysql2 gemインストール時のトラブルシュート HrsUed 18/11/28
19/04/16264
21183 Ruby のエラーメッセージを読み解く(初心者向け)その 1 scivola 16/03/05
19/08/06256
10684 日本正式リリースしたStripeを使ってサブスクリプション型決済システムを実装する tady 16/10/04
18/05/21394
9285 find、find_by、whereの違い tsuchinoko_run 18/03/17
18/03/17216
14886 はじめてのRails API c5meru 17/12/16
17/12/16296
11687 フロントエンド全然わからないマンが、ちょっとでも見た目のいいWebサービスを作ろうとしてやったこと liukoki 18/03/21
18/03/251018
8388 YAMLとは何か? - いつもRailsの設定ファイルで出てくるやつの正体 Yama-to 15/07/27
15/08/08385
9689 20万pv/月達成のwebサービスのRailsソースコード、全部見せます! kent_ear 18/07/31
19/08/22788
6090 Rubyのメソッドの引数受け渡しまとめ raccy 16/07/17
19/12/25233
11291 (Capistrano編)世界一丁寧なAWS解説。EC2を利用して、RailsアプリをAWSにあげるまで naoki_mochizuki 16/02/01
19/11/14301
10092 Ruby on RailsのAjax処理のおさらい ka215 15/01/20
19/06/25728
7793 AWS:無料でSSL証明書を取得する方法 iwaseasahi 17/06/03
18/01/13255
11894 Rails 5 + ActionCableで作る!シンプルなチャットアプリ(DHH氏のデモ動画より) jnchito 15/12/22
16/07/13644
7895 今更聞けないpryの使い方と便利プラグイン集 k0kubun 14/12/21
16/01/16752
6096 並行処理、並列処理のあれこれ Kohei909Otsuka 18/02/14
18/02/15215
14197 正規表現のパフォーマンスの話をされても全くピンと来なかった僕は、backtrackに出会いました。 mochizukikotaro 16/05/28
17/04/04539
3598 最速!MacでRuby on Rails環境構築 narikei 15/12/12
19/03/05318
7799 Ruby on Rails+ReactでCRUDを実装してみた yoshimo123 18/02/17
19/02/28240
125100 【初心者向け】RailsのActive Recordの解説&メソッドまとめ ryokky59 18/10/05
18/10/05184
175
1行目が総数。2行目が直近1年。 ↩
- 投稿日:2020-04-06T21:31:27+09:00
Rails ActiveAdminのインストール時にエラー(superclass mismatch for class Application (TypeError))
はじめに
railsでactiveadmin gemを使用したアプリを作成する際、ActiveAdminインストールで、エラーが発生した。
そのエラー発生原因が思いもよらなかった(railsプロジェクト名によるもの)ため、発生情報と解決方法を記す環境
- debian : 10.3
- ruby: 2.6.6 (rbenv使用)
- rails: 5.2.4.2
発生情報
"active_admin"という名前でプロジェクトを作成(rails new)し、gemにactiveadminを追加&bundle install (ココまでは問題なし)
その後、Userモデルの作成、DBのテーブル実施後、以下のactive_admin似必要なファイルインストールを実行したタイミングでエラー発生。$ rails generate active_admin:install /home/great084/jinsei/active_admin/config/application.rb:21:in `<module:ActiveAdmin>': superclass mismatch for class Application (TypeError) ・・・以下略原因
railsプロジェクト名が"active_admin"であったため。それ以上は私の知識ではわからず。
※active_adminという名前は禁止されている(模様)対処
active_adminというrailsプロジェクトは一旦削除し、他の名前(active_admin_apl)で再度プロジェクト作成。
→rails generate active_admin:install
でエラー発生せず。参考
Ruby-on-Rails: ActiveAdmin SuperClass Mismatch TypeError(stacoverflow.com)
- 投稿日:2020-04-06T19:47:58+09:00
1アクションで複数のビューを切り替えて表示しようとしたが、結局1アクション1ビューが良いという話
●はじめに
今回がQiita初投稿です。ポートフォリオを作成中に学んだ事をアウトプットする事を目的に始めました。
初歩的な内容が多いかと思いますが、是非、これからポートフォリオを作成する方に対し、役立てればという思いで発信しております。●概要
トップページに「投稿一覧」「いいねした投稿一覧」「自分の投稿一覧」というリンクを作成し、それぞれを1つのindexアクションにまとめようとようとした。しかしやはり基本的には1アクション1ビューが良いとのことでした。
●理由
・1つにまとめてしまうと、対応するURLがわかりにくくなる
・Railsの設計思想であるMVCの観点からやはり望ましい●実装方法
ちなみに、それでもあえて1つにまとめたいなら、パラメータを利用します。
if params[:name] == "post" @questions = Post.all elsif params[:name] == "like" 処理 elsif params[:name] == "user_post" 処理ですがおすすめとしてはアクションで分けてしまう事。
「例1」
・posts#index
・users#like_index
・users#post_indexリソースでまとめたいというこだわりがあるのであればコントローラーを作成する方法も。
「例2」
・posts#index
・users#show
・users::favorite#index●まとめ
Railsの場合は1アクション1ビューという基本を守った方が良い。
その場合、実装方法には様々な方法があるため、色々試して見るとより理解が深まるかもしれません。
- 投稿日:2020-04-06T19:12:08+09:00
Rails ウィザード形式導入について 3
はじめに
Rails ウィザード形式導入について 1 はこちらをクリック願います。
Rails ウィザード形式導入について 2 はこちらをクリック願います。
チーム開発でフリマサイトを開発致しました。
その際、ユーザーの新規登録画面でウィザード形式を導入致しましたので、内容を整理します。
もうすでにご存知の方、省略の仕方等ご存知でしたら、ご教授願います。前提
- ユーザー情報(User)については 以下 A と記述します。
- 住所情報(Destination)については 以下 B と記述します。
Bの登録の各アクション(create)とビュー(new,create)
ルーティング設定(new,create)
- B情報を登録するページを表示するnew_destinationアクションのルーティングを設定します。
- また、B情報を登録するcreate_destinationアクションのルーティングも設定します。
config/routes.rbRails.application.routes.draw do devise_for :users, controllers: {registrations: 'users/registrations'} #ここから↓ devise_scope :user do get 'destinations', to: 'users/registrations#new_destination' post 'destinations', to: 'users/registrations#create_destination' end #ここまで↑ root to: "top#index" endB情報のビューファイルの作成(new)
- 該当するビューファイルであるnew_destination.html.hamlを作成しまーす!
- 参考程度にみてください。このまま入力するとエラーが出るかも・・・です。
app/views/devise/registrations/new_address.html.haml.opi = form_for @destination do |f| .postal-code .postal-code__a .postal-code__a__a1 = f.label :post_code,"郵便番号" .postal-code__a__a2 必須 .postal-code__b = f.text_field :post_code,size:37, maxlength:7 .prefectures .prefectures__c .prefectures__c__c1 = f.label :prefecture_code_name,"都道府県" .prefectures__c__c2 必須 .prefectures__d = f.collection_select :prefecture_code, JpPrefecture::Prefecture.all, :name, :name, {prompt:'--'}, {class: "shipping__area-input-1"} .municipality .municipality__e .municipality__e__e1 = f.label :city,"市区町村" .municipality__e__e2 必須 .municipality__f = f.text_field :city,size:37 .address .address__g .address__g__g1 = f.label :house_number,"番地" .address__g__g2 必須 .address__h = f.text_field :house_number,size:37 .building .building__i .building__i__i1 = f.label :building,"建物名" .building__i__i2 任意 .building__j = f.text_field :building,size:37 .phone .phone__number1 .phone__number1__kk = f.label :phone_number,"電話番号" .phone__number1__yy 任意 .phone__number2 = f.text_field :phone_number,size:37,maxlength:11 .register %input#submit_button2{:name => "submit", :type => "submit", :value => "登録する"}/ここで一言!
- createアクション内で必要なインスタンス変数を定義してrenderしてます。
- なので、new_destinationアクションをコントローラ内に定義する必要はありませ-ん!
create_destinationアクションを定義する
app/controllers/users/registrations_controller.rbclass Users::RegistrationsController < Devise::RegistrationsController # 省略 def create_destination @user = User.new(session["devise.regist_data"]["user"]) @destination = Destination.new(destination_params) unless @destination.valid? flash.now[:alert] = @destination.errors.full_messages render :new_destination and return end @user.build_destination(@destination.attributes) @user.save sign_in(:user, @user) end protected def destination_params params.require(:destination).permit(:post_code, :prefecture_code, :city, :house_number, :building, :phone_number) end # 省略 end2ページ目で入力した住所情報のバリデーションチェック
- createアクションと同様に、valid?メソッドを用いて、バリデーションチェックを行います。
2ページ目の情報とSessionで保持していた情報とあわせ、ユーザー情報として保存
- build_destinationを用いて送られてきたparamsを、保持していたsessionが含まれる@userに代入します。
- saveメソッドを用いてテーブルに保存します。
ログインをすること
- 今のままだとユーザーの新規登録ができても、ログインができてません。
- sign_inメソッドを利用してログイン作業を行います。
最後にdestination_createに対応するビューを作成
- 該当するビューファイルであるcreate_destination.html.hamlを作成しまーす!
- 参考程度にみてください。このまま入力するとエラーが出るかも・・・です。
app/views/devise/registrations/create_destination.html.haml.main .done 会員登録完了 .mozi ありがとうございます。 会員登録が完了しました。 .login2 = link_to "トップへ戻る", root_path以上で完了です!できました?
個人で開発されるアプリにもぜひ導入してみてください!
UI性も増して、Looks Goodかと!さいごに
日々勉強中ですので、随時更新します。
皆様の復習にご活用頂けますと幸いです。
- 投稿日:2020-04-06T19:11:07+09:00
【Rails】GoogleBooksAPIを叩いて書籍検索機能作る【Ajax】
現在作成中のポートフォリオの最後の機能、
GooglebooksAPIを叩いて書籍検索をする機能がやっとできましたので、その奮闘記をここに記します。(ちなみにAWSデプロイエラー地獄にハマっている間に書いてます)
GoogleBooksAPIとは
Googleが提供している書籍情報のAPIです。
無料且つ簡単に利用できるので、書籍関連アプリを作る際に結構利用されてるみたいです。簡単に言うと、
https://www.googleapis.com/books/v1/volumes?q=おおきく振りかぶって&country=JP&maxResults=30
みたいな感じでキーワードを入れるとその情報がjson形式にされたファイルが表示されます。
これを利用すれば簡単に書籍情報をゲットできると言うわけですね〜。
便利。では早速取り掛かりましょう。
環境
- Ruby 2.6.3
- Rails 5.2.2
- Docker
- MacOS
前提
- 投稿機能はすでに作られている(post_controller)
最終目標
最終的にできて欲しいのは以下。
- 検索ボックスにキーワードを入力する
- キーワードに基いた検索結果が投稿フォームの下に表示される
そのために必要な処理
- 検索フォームにキーワードを入力
- キーワードをコントローラ側で受け取る
- 受け取ったキーワードを元にAPIを叩く
- 叩かれたAPIから情報を取得する
- 取得した情報を投稿画面に渡す
- 渡された情報でAjaxを発火させて投稿画面の部分テンプレートを更新する
大体前準備はこんな感じです。
以下からは具体的にコードの方を見ていきます。
検索フォームの設置
_search.html.erb<%= form_tag(new_post_path, method: :get, remote: true) do %> <input type="text" name="keyword" id="keyword" placeholder="書籍を検索"> <button type="submit"><i class="fas fa-search fa-lg"></i></button> <% end %>こちらのフォームではmethodをgetに設定しています。
理由は後ほど詳しく説明しますが、ざっくり言うと入力されたキーワードの送り先がpost_controllerのnewアクションだからです。また、remote:trueを設定しておくことでjsファイルを探してAjaxを発火させてくれます。
APIを叩くモジュールを作成
最初はコントローラーにAPIを叩く処理も書いていたのですが、かなりコードがごちゃごちゃしてしまったのとエラーが発生しやすかったので、別にモジュールを作って叩く処理はそこでまとめました。
app/lib/book.rbmodule BooksApi extend self def get_url(keyword) url = URI.encode("https://www.googleapis.com/books/v1/volumes?q=#{keyword}&country=JP&maxResults=30") response = HTTParty.get(url) end endget_urlは引数にkeywordが設定されており、画面から入力されたパラメータを受け取ってAPIの#{keyword}部分に渡されます。
HTTParty.get(url)でAPIを叩いて情報を取得します。
このHTTPartyは、自動でjsonを解析してrubyのhashに変換してくれる優れもの。#api関連 gem 'json' gem 'httparty'gemをインストールしときましょう。
コントローラーに取得した情報を渡す
検索フォームから受け取ったパラメーターを先ほど作成したモジュールを経由してAPIを叩き、コントローラーで取得します。
posts_controller.rbrequire 'net/http' require 'uri' require 'json' require 'httparty' class PostsController < ApplicationController #初期化 @results = [] def new if @results.present? @post = Post.new else @post = Post.new #url_from_keywordメソッドの呼び出し @results = url_from_keyword end end #パラメータを取得しkeywordに代入 def url_from_keyword keyword = params[:keyword] BooksApi.get_url(keyword) endまず一番上のrequire部分ですが、これはAPIを叩くために必要なものなのでちゃんと書いときましょう。
これがないとすぐエラーが出ます。では各アクションについて。
url_from_keywordアクション
posts_controller.rbdef url_from_keyword keyword = params[:keyword] BooksApi.get_url(keyword) endこれはパラメーターを受け取って、その情報を先ほど作成したモジュールに引数で渡してAPIの情報を取得する処理を行っています。
しかし、フォームから送信するパラメーターを直接ここに投げるわけではありません。
それが先ほどのmethod:getの話につながります。
newアクション
posts_controller.rbdef new if @results.present? @post = Post.new else @post = Post.new @results = url_from_keyword end endnewアクションではAPIの情報があるときとない時で処理を分けています。
ない時は@rersultsに初期値で空配列を入れており、処理はPost.newだけです。
APIが叩かれた場合はその情報を@resultsに入れてるので、Post.newと@resultsの情報の表示処理を行います。
先ほど検索フォームを作成した際、methodをgetに設定していたのはこのためです。
routes.rbresources :posts do post 'add' => 'likes#create' delete '/add' => 'likes#destroy' endnewアクションはresoucesでgetになっており、送られたパラメータの処理を行うのはnewアクション内ですので、methodもそれに合わせて設定していたわけですね。
検索結果一覧画面
では処理が完了したのでこの情報を表示させましょう。
一覧画面の部分テンプレート
_results.html.erb<div class="wrap" id="ajax-response"> <div class="container-fluid"> <div class="row"> <% for i in 0..29 do %> <div class="result-box"> <% if @results["items"][i]["volumeInfo"]["imageLinks"].nil? %> <img src="/images/noimage.png"> <% else %> <img src="<%= @results["items"][i]["volumeInfo"]["imageLinks"]["thumbnail"] %>" > <% end %> <% if @results["items"][i]["volumeInfo"]["title"].nil? %> <h3 class="title">情報がありません</h3> <% else %> <h3 class="title"><%= @results["items"][i]["volumeInfo"]["title"] %></h3> <% end %> <% if @results["items"][i]["volumeInfo"]["authors"].nil? %> <p class="author">情報がありません</p> <% else %> <p class="author"><%= @results["items"][i]["volumeInfo"]["authors"][0] %></p> <% end %> </div> <% end %> </div> </div> </div>正直これはあまり良い書き方ではないのですが…時間に追われていたというのもあってとりあえず表示を目指して書きました。
["items"][i]["volumeInfo"]["title"]みたいなのがいくつかあると思いますが、これは先に挙げたリンクのjsonです。
「itemsの中のi番目のvolumeInfoの中のtitle」といった感じで情報を表示しています。
表示したい数だけfor文で回したらいい感じに一覧画面ができました。
Ajax
app/views/posts/new.js.erb$('#render-results').html("<%= escape_javascript(render partial: "posts/results", locals: { results: @results }) %>");Ajaxは以前書いたいいね機能とほとんど同じです。
app/views/posts/new.html.erb<div class="container-fluid"> <div class="row"> <div class="center-block mx-auto"> <div id="search-box" class="center-block mx-auto"> <%= render 'posts/search' %> </div> <%= form_tag(posts_path,{method: :post}) do %> <%= render 'shared/post_form' %> <% end %> </div> <div id="render-results"> </div> </div> </div>投稿画面の下部にあるid="render-results"を取得して、そこに先ほどの検索結果一覧画面の部分テンプレートを挿入してる感じですね。
ここまでできたら上手くAjaxが発火して表示されてくれるはず。
ここでのハマりポイント
とか言いながら、この検索結果一覧表示画面には一つ問題があります。
それは、以下のようなエラーが出てしまうことです。undefined method [] for:NilClass意味としては「nilの時の[]が定義されてへんで」といった感じらしいので、
例えば「サムネイルの画像がない」みたいな一部の情報が欠けてる場合に発生してしまします。こいつの上手い対処法が分からず結構右往左往していました。
結局これも応急処置みたいな感じになってしまったのですが、
「定義されてへんのがアカンのやったら、定義したらええやん」
ということで、以下のように対処しました。app/lib/nil_class.rbclass NilClass def [](*) nil end endposts_controller.rbclass PostsController < ApplicationController @results = [] require 'nil_class' ...モジュールを作ったディレクトリにnilclass用のファイルを作り、それをrequireで呼び出してます。
これでとりあえず表示は問題ないです。
まとめ
今回このポートフォリオを作る中で結構ミソのとこではあったので、自分なりに色々がんばりました。
ぶっちゃけコードは美しくないのでそこはこれから改善したいと思います…。
ひとまず作品自体は大体完成したので、あとはデプロイだけです。
が、AWSのデプロイが全然できなくて絶賛躓き中でございます。
無事デプロイが完了しましたらその辺の奮闘記も書きたいと思いますので、その時はどうぞよろしくお願い致します。
ではでは。
- 投稿日:2020-04-06T17:24:42+09:00
Railsにおける例外処理
rails db:seed
rails db:seedコマンドは、db/seeds.rbの記述に基づいて、データベースにレコードを作成するコマンドです。
クローン直後に投入したい初期データがある場合に利用します。
ターミナル# 初期データの投入 $ rails db:seed【例】チケット販売を例とします
db/seeds.rbusers = [] 10000.times do |i| # usersに10000件新規ユーザーの情報を格納する users << User.new(name: "dummy-#{i+1}", ticket_count: 0) end # importメソッドの引数に配列を渡して、まとめてレコードを作成する User.import users User.find(500).update(ticket_count: 123456789)今回は初期データの作成に、activerecord-importというgemを利用しています。
これは、通常通り10000回User.createするよりも、高速に大量のレコードを作成できるからです。
参考リンク
https://qiita.com/xend/items/79184ded56158ea1b97a例外
例外とは、ある処理を実行した際の結果が、期待されるものと異なる状況を指します。 RubyおよびRuby on Railsでは、Exceptionというクラスを継承する形で様々な例外が定義されています。NoMethodError、SyntaxError などは、全てExceptionクラスの子孫クラスであり、例外です。例外が発生すると、それ以降の処理は中止され、実行されなくなってしまいます。
今回rails db:seedを実行して投入した初期データには、意図的に例外を発生させる値が投入されているものがあります。db/seeds.rb# ticket_countをint型で許容できる最大の値にする User.find(500).update(ticket_count: 123456789)idが500のユーザーのticket_countを、123456789に変更しています。これは、SQLのinteger型が許容できる最大の値であり、もし123456789より大きな値を保存しようとすると、RangeErrorという例外が発生し、保存に失敗します。ターミナルからrake distribute_ticket:executeを実行してみると、例外の発生するidが500までのユーザーについては、ticeket_countが10増加し、idが500番目以降のユーザーについては、例外が発生してしまったために、処理が中止され、ticket_countが増えていません。
例外処理
例外処理とは、例外が発生した場合に実行する処理のことを指します。Ruby on Railsの開発を行う際に、よく利用するのがrescueです。
上記のrubyプログラムを実行すると、「1 / 0」の処理を行った際に、ZeroDivisionErrorという例外が発生します。これは、数字を0で割ろうとすると発生する例外です。
beginブロックの内部で例外が発生したため、rescue以下の処理が実行されます。rescue
rescueとは、発生した例外を捕捉し、例外が起こった際に呼び出される条件節です。
例外が発生しそうな部分をbeginから始まるブロックで囲み、ブロックの内部にrescueを記述して使用します。
サンプルbegin # 数字を0で割ろうとすると、ZeroDivisionError例外が発生する 1 / 0 rescue # 例外が発生した時にrescue以下の処理が呼ばれる puts '0で割ることはできません' end通常、each, times, whileなどの繰り返しの最中に例外が発生した場合、繰り返し処理は途中で中止され、次のループが実行されることはありません。ただし、繰り返し処理の内部にrescueを記述していた場合、例外が発生したとしても、次のループに移ることができます。
大量のレコードを扱う処理で、例外が発生しても繰り返しを続行したい場合には、rescueを使いましょう。トランザクション
複数のレコードの更新を1つにまとめて行うことを指します。トランザクションを用いることで、「全て実行されるか、それとも全て実行されないか」という1か0の状況を作ることができます。
サンプル# ECサイトの購入処理を模した架空のコード ActiveRecord::Base.transaction do current_user.pay!(@product.price) current_user.confirm_purchase!(@product) end上記のサンプルは、購入処理を模した架空のコードです。pay!メソッドで商品の料金を払い、confirm_purchase!メソッドで商品の注文を確定させています。料金の支払いと、商品の購入の確定は、常に1つのまとまりとして考えます。トランザクションを用いることによって、「料金の支払いに失敗したけど、商品は購入できた」「料金は支払ったけど、注文の確定に失敗し商品が届かなかった」といった事態を防ぐことができます。
参考リンク
例外と呼んでいたものは、全てこのExceptionクラスを継承しています。
Ruby Exceptionクラス ドキュメント
ActiveRecord Transactions ドキュメント(英語)
- 投稿日:2020-04-06T13:44:09+09:00
Elastic Beanstalkでrails on Docker した時のメモ
mysqlへの接続エラー
Elastic Beanstalk(EB)で環境を作成する時にmysql(RDS)も一緒に作成した。
この時にmysqlのpassword(8文字以上)の設定をしたのだが、適当に数字を入力しただけでは、Railsがmysqlに接続できない。
Mysql2::Error: Access denied for user 'username'@'host' (using password: YES)ここで設定したpasswordは環境変数(RDS_PASSWORD)で定義されているので、Railsのdatabase.ymlで以下のように使える。
password: <%= ENV["RDS_PASSWORD"] %>
エラーの原因を探ろうと、アプリケーションに直接潜入してみることに。
ローカルからsshでEBのEC2に入って、そこで
$ sudo docker run -i -t コンテナid bash
でdockerコンテナに入り、以下を入力しコンソールからmysqlへ接続。
$ mysql -h $RDS_HOSTNAME -u $RDS_USERNAME -p $RDS_DB_NAME
でEnter、passwordの入力を求めれ、EBで設定した先ほどのpasswordをベタ打ち、最後にEnterしてみると......繋がった。
この結果から考えれる原因は
1. セキュリティーグループやサブネット周り
2. 環境変数が正しく定義できていない最初はセキュリティーグループやサブネット周りの問題かと思って色々調べて試してみたが、繋がらなかった。
憔悴しきったところでまさかと思いEBのコンソールからmysqlのpasswordを変更してみると...
繋がった。
解決策
mysqlのpasswordの設定で一文字でも文字列を入れてあげると問題なく繋がるようだ。数字だけ では、繋がらない。
考えられる原因
おそらく、Railsがmysqlへ接続する時に使う環境変数が文字列に変換されてしまっているのだろう。
- 投稿日:2020-04-06T13:42:56+09:00
Rails Consoleでselect文などを記述する
メモ
ActiveRecord::Base.connection.select_all("select * from users").to_hashめちゃくちゃ参考になる記事
https://qiita.com/yut_h1979/items/4cb3d9a3b3fc87ca0435
- 投稿日:2020-04-06T12:59:05+09:00
enum、scopeのロジック
enum
enumはint型、boolean型で定義されたカラムを、文字列で表現できるようにする機能です。
【例】class Drink < AppricationRecord # Drinkモデルのkindrカラムのenumを定義する # DBに保存されている値が0の時はtea, 1の時はcoffee、2の時はbeerを意味する enum kind: [:tea, :coffee, :beer] end【例】
@drink = Drink.new(kind: 1) @drink.kind # => 'coffee' # 数字ではなくenumで定義したキーワードが返ってくるenumを利用すると、数字と対応した文字列を返り値として出力できるようになります。
scope
scopeはモデルに対する絞り込みの条件に名前をつけて、メソッドのように呼び出し可能にする機能です。よく使う検索ロジックはscopeにしておくことによって、後から簡単に再利用できるようになります。
【例】今回はTaskモデルに「incoming」という名前でscopeを定義します。app/models/task.rbclass Task < ApplicationRecord enum kind: { individual: 0, work: 1, others: 2 } scope :incoming, -> { where('start_at > ?', Time.zone.now) } end定義したscopeを使って@tasksを再定義します。
app/controllers/tasks_controller.rbclass TasksController < ApplicationController def index @task = Task.new # モデルに定義したscopeはメソッドのように呼び出せる @tasks = Task.incoming.order(start_at: :asc) end # 以下省略参考リンク
enumリファレンス(英語)
enum_help Githubリポジトリ
Rails ModelのScope(スコープ)の使い方
- 投稿日:2020-04-06T12:24:55+09:00
素人がWebサービスを自分で作る備忘録(設計編)
はじめに
今回は前準備編の続きです。そちらに筆者のスキルレベルやこの記事の目的などが書いてありますので、先にお読みください。
Webサービスの設計
今回は前回の内容とほんのすこーしだけ重なる部分があるのですが、サービスの設計で何を行ったかを書いていきたいと思います。
まず、前回行ったWebサービスの企画の段階ではザックリどのような物を、何で、どんな機能を持たせるみたいなことを考えました。
そしてここから以下の設計を行っていきます。1.ワイヤーフレームを描く
2.それぞれのページのURLを考える
3.データベースの設計
4.ワイヤーフレームの見直し
5.やることの確認ワイヤーフレームとは
ワイヤーフレームっていうのはすごーく簡単に書いたページの全体像です。これを書くことによってサービスの全体像がイメージしやすくなり、作業する人たちのイメージのズレを少なくすることができます。(一人でやるんですが。。。)
今回は手書きでさっくりと作成しました。手順は
1.そのページに必要な情報を全て書き出す。(ピックアップ)
まずは何が必要なのか洗い出しましょう。ロゴとか登録フォームとか色々あると思うます。2.同じ性質のものをまとめる(グルーピング)
同じ性質のもの例えばメールアドレスとか電話番号とかは近くにおいといた方がユーザーが何か問い合わせたい時 に便利ですよね。なのでここで分けておきましょう。3.情報に優先順位を付ける(ランキング)
何を目立たせれば良いのか考えましょう。
例えばコーポレートサイトであれば会社名とか会社の概要とかですかね?今回は投稿機能がメインなのでログイン状態に関わらず投稿一覧画面は目立たせて見ます。ログイン後の画面では投稿フォームを目立たせるのもいいかなと思っています。4.レイアウトを考える
ここまで洗い出した情報をもとに簡単なレイアウトを作っていきます。
本当ならこの後にIllustratoやCacooなどのツールを使用して清書するのがいいのかもしれませんが今回はやりません。
ちなみにサイトを訪れる人は左上に最初に目が行きます。その為、目立たせたい情報は左上に配置するといいです。そして左上からそのまま左下へまたは、左上から右へといくことが多いです。これをF字パターンと言います。
こういったことから有名サービスのロゴは基本的に左上にあるんだと思います。URL決定
ワイヤーフレームが描けたらそれぞれのページのURLを考えていきましょう。(/loginとか/signupとか。。。)
まあ、初めてでそんなに複雑なアプリを作るわけではないので基本的にrailsチュートリアルで使ったようなURLでいきます。DB設計
Webサービスを作るのであればDBを使用することになりますが。その時に何のデータをどのテーブルに入れるのかということを考えていきます。
こんな感じ
・users
id:integer
name:string
email:stringこれも手書きd、、、
ワイヤーフレームの見直し
ここまでできたらワイヤーフレームで書いた内容がURLとDBで再現できるかを考えましょう。
SQLコマンドがイメージできるようにしておくと後が楽です。やることの確認
ここでいうやる事というのは、トップページの画面を作って、ログイン機能をつけて、ログアウト機能もつけてみたいなことです。ザックリページ単位でいいと思いますのでまとめておきましょう。
そして実装へ
ここまでやったらあとはガシガシ実装していくだけです。かなり大雑把に行ったので手戻り作業が多発することが予想されますがそういったところも今後の為にまとめていけたらいいなと思っております。
ここまで行ったこと
・基礎学習
・Webサービスの企画
なぜ作るのか
どのような物を作るのか
どういった機能が必要なのか
・Webサービス設計
ワイヤーフレーム作成
URL決定
画面遷移図の作成
データベース設計
タスクの確認参照元
初めての個人WEBサービスを作り始める前にやるべき設計
(https://www.muratayusuke.com/2016/01/16/how_to_design_web_app/)
- 投稿日:2020-04-06T12:12:36+09:00
MVCのリファクタリング
ビューのリファクタリング
ビューファイルで複雑な呼び出しを行っている場合
【例】
app/views/articles/index.html.erb<% Article.where(status: 1).order(likes_count: :desc).limit(10).each do |article| %> <%= article.title %> <% end %>この例では「表示処理を行う」ことを責務としたビュー上で、データの呼び出しに関する複雑な処理が書かれています。
このような複雑な処理は、「データ処理を行う」ことを責務としたモデルに記載します。なぜかというとビューファイルに複雑な記述があると、コードの視認性が悪くなります。また、モデルに記述すると、様々なアクションで用いることができます。
また、モデルに定義した処理を行った上で、コントローラでインスタンス変数として定義します。
modelclass Article < ActiveRecord::Base scope :popular, -> { order(likes_count: :desc) } enum status: { draft: 0, published: 1 } endcontroller
def index @articles = Article.published.popular.limit(10) endview
<% @articles.each do |article| %> <%= article.title %> <% end %>同じ処理を繰り返し記述している場合
app/views/books/show.html.erb<% if user_signed_in? %> <% if current_user == @book.user %> <%= link_to "編集", edit_book_path(@book) %> <% end %> <% end %>app/views/comments/show.html.erb<% if user_signed_in? %> <% if current_user == @comment.user %> <%= link_to "編集", edit_comment_path(@comment) %> <% end %> <% end %>上記の2つのコードでは「ユーザーがサインインしているか」「そのインスタンスに紐付いたユーザーがログインしているユーザーと一緒であるか」を判定する処理が共通しています。
この処理はアプリケーション内で使用頻度が高いものだと考えられるので、helperに処理を切り出してどのビューからでも呼び出せるようにします。app/helpers/application_helper.rbdef current_user_has?(instance) user_signed_in? && current_user == instance.user endapp/views/books/show.html.erb<% if current_user_has?(@book) %> <%= link_to "編集", edit_book_path(@book) %> <% end %>app/views/comments/show.html.erb<% if current_user_has?(@comment) %> <%= link_to "編集", edit_comment_path(@comment) %> <% end %>複雑な条件分岐がある場合
view
<% if @book.published? %> <% if @book.popular? %> <%= link_to "詳細", book_path(@book) ,class: "popular" %> <% else %> <%= link_to "詳細", book_path(@book) ,class: "normal" %> <% end %> <% else %> <div class=normal>閲覧不可</div> <% end %>ビューに複雑な条件分岐がある場合もhelperに処理を移動します。
helperではビューで使えるヘルパーメソッドが使用できます。
helperdef book_link(book) class_name = book.popular? ? "popular" : "normal" if book.published? content_tag :a, "詳細", class: class_name else content_tag :div, "閲覧不可", class: class_name end endview
<%= book_link(@book) %>複雑な条件分岐をhelperに移動することでビューの見通しが良くなります。
helper内は自由にコードを記述できるので、ビュー内で条件分岐をするよりもスッキリとわかりやすいコードにすることができます。同じビューを複数回記述してしまっている場合
app/views/books/show.html.erb<div class="book"> <span> <%= @book.title %></span> <p><%= @book.description %></p> <span><%= @book.author %></span> </div>app/views/books/index.html.erb<div class="book_list"> <% @books.each do |book| %> <div class="book"> <span> <%= book.title %></span> <p><%= book.description %></p> <span><%= book.author %></span> </div> <% end %> </div>繰り返し複数の箇所で使われるビューは部分テンプレートとして切り出して使用します。
app/views/books/_book.html.erb<div class="book"> <span> <%= book.title %></span> <p><%= book.description %></p> <span><%= book.author %></span> </div>app/views/books/show.html.erb<%= render partial: "book", locals: { book: @book } %>app/views/books/index.html.erb<div class="book_list"> <%= render @books %> </div>部分テンプレートとして切り出して使用する時の注意点は、「部分テンプレート内でインスタンス変数を使用しない」ことです。
部分テンプレート内では呼び出し元で定義されているインスタンス変数を使用することができます。しかし、これをしてしまうと呼び出し元のインスタンス変数の名前が異なる時に部分テンプレートを呼び出せなくなってしまいます。コントローラーのリファクタリング
複数のコントローラに同じ処理が記述されている場合(concerns)
開発の規模が大きくなるにつれ複数のコントローラに同じような処理が繰り返し記述されることがあります。この場合、
app/controllers/concernsにファイルを追加し、必要箇所で読み込ませます。
親コントローラにメソッドを定義する
などの方法でコントローラの記述を共通化することができます。
concerns ディレクトリに複数モデルで共通するコードをモジュールとして定義することでソースコードの見通しが改善できます。
【例】app/controllers/products_controller.rbclass ProductsController < ApplicationController before_action :set_cart ~省略~ private def set_cart @cart = Cart.find_by(id: session[:cart_id]) if @cart.nil? @cart = Cart.create session[:cart_id] = @cart.id end end endapp/controllers/top_controller.rbclass TopController < ApplicationController before_action :set_cart ~省略~ private def set_cart @cart = Cart.find_by(id: session[:cart_id]) if @cart.nil? @cart = Cart.create session[:cart_id] = @cart.id end end end上の2つのコントローラではどちらもset_cartというメソッドを定義して、インスタンス変数にカートのインスタンスを代入しています。
カート情報はこの2つのコントローラ以外でも頻繁に使用する可能性がありますが、そのたびにこのメソッドを追加していくのは好ましくありません。そこで以下のようにconcernsに処理を切り出してあげることで同じ処理を共通化できます。app/controllers/concerns/current_cart.rbmodule CurrentCart extend ActiveSupport::Concern private def set_cart @cart = Cart.find_by(id: session[:cart_id]) if @cart.nil? @cart = Cart.create session[:cart_id] = @cart.id end end endapp/controllers/products_controller.rbclass ProductsController < ApplicationController include CurrentCart before_action :set_cart endapp/controllers/top_controller.rbclass TopController < ApplicationController include CurrentCart before_action :set_cart endユーザーのカート情報を扱うためにそれぞれのコントローラでこのset_cartを定義する必要がありますが、定義したCurrentCartを使用したいコントローラで読み込むだけでそこに定義されているメソッドを使用することができるようになります。
複数のコントローラに同じ処理が記述されている場合(継承)
共通の処理を持つコントローラが同じ親コントローラを継承していれば、親コントローラに記述することで処理を共通化することができます。
app/controllers/sales_controller.rbclass SalesController < ApplicationController before_action :authorize_owner private def authorize_owner redirect_to root_path unless current_user.owner? end endapp/controllers/customers_controller.rbclass CustomersController < ApplicationController before_action :authorize_owner private def authorize_owner redirect_to root_path unless current_user.owner? end end例えば、上の2つのコントローラではauthorize_ownerを呼び出しています。この場合、SalesControllerとCustomersControllerはどちらもApplicationControllerを継承しているため、以下のように処理を共通化することができます。
app/controllers/application_controller.rbdef ApplicationController < ActionController::Base private def authorize_owner redirect_to root_path unless current_user.owner? end endapp/controllers/sales_controller.rbclass SalesController < ApplicationController before_action :authorize_owner endapp/controllers/customers_controller.rbclass CustomersController < ApplicationController before_action :authorize_owner end複数のアクションに同じ処理が記述されている場合
同じコントローラ内で同じような処理が繰り返し記述されている場合はcallbackを用いて共通化します。
controllerdef BookController < ApplicationController def index @books = Book.all end def show @book = Book.find(params[:id]) end def new @book = Book.new end def create Book.create(book_params) end def edit @book = Book.find(params[:id]) end def update @book = Book.find(params[:id]) @book.update(book_params) end def destroy @book = Book.find(params[:id]) @book.destroy end private ~省略~ end上のコントローラではshow, edit, update, destroyで共通して@book = Book.find(params[:id])という処理を行っています。
このような処理はbefore_actionなどのcallbackを利用して共通化します。
controllerdef BookController < ApplicationController bofore_action :set_book, only: [:show, :edit, :update, :destroy] def index @books = Book.all end def show end def new @book = Book.new end def create Book.create(book_params) end def edit end def update @book.update(book_params) end def destroy @book.destroy end private def set_book @book = Book.find(params[:id]) end ~省略~ endset_bookをbefore_actionで呼び出すことによってそれぞれのアクションで何をしているのかがよりわかりやすくなりました。
コントローラに複雑な処理を記述している場合
コントローラのコード量が多くなっている場合、本来モデルで行うべき処理がコントローラに書かれている可能性が高いです。このままでは、コントローラを変更する時に影響範囲が広くなってしまい、バグが発生する可能性が高まります。
この場合には、モデルのメソッドに処理を移動します。
before# controller @user = User.find(params[:user_id]) @user.name = params[:user_name] if params[company_name] @user.company_name = params[company_name] company = Company.find_by(name: params[company_name]) if company @user.company = company end end @user.saveafter
# controller @user = User.find(params[:user_id]) @user.update_company(params[company_name]) # model class User < ActiveRecord::Base def update_company(company_name) if company_name self.company_name = company_name company = Company.find_by(name: params[company_name]) if company self.company = company end end save end endこうすることで、他のアクションでもupdate_companyを呼び出せるようになり、アプリケーション全体で処理を統一することができます。
モデルのリファクタリング
ビューやコントローラから呼び出される様々な処理はモデルに集約されていくために、モデルは肥大化し易いです。そこで、モデルに書かれた処理を幾つかの観点で切り分けていくことでモデルの見通しを改善する方法を書いていきます。
Decorator(デコレーター)
【例】
app/models/user.rbclass User < ActiveRecord::Base def full_name "#{family_name} #{first_name}" end def full_name_kana "#{family_name_kana} #{first_name_kana}" end endDecorator(デコレーター)とはビューとモデルの中間に位置し、モデルやビューなどに実装されやすい表示ロジックやフォーマットなどの責務を引き受けるクラスです。
モデルにビューでしか使用しないメソッドが増えていくことがあります。上のfull_nameやfull_name_kanaと言ったメソッドがその例です。こうしたメソッドをデコレーターに移動することでコードの見通しが改善されます。
Railsでデコレーターを使用する場合にはdraperやactive_decoratorと言ったgemを使う方法が一般的です。今回はdraperを使った例を記述します。
active_decorator Github リポジトリ
「デコレーター」を導入するためのgemです。
【例】app/decorators/user_decorator.rbclass UserDecorator < Draper::Decorator delegate_all def full_name "#{family_name} #{first_name}" end def full_name_kana "#{family_name_kana} #{first_name_kana}" end endapp/controllers/users_controller.rbclass UsersController < ApplicationController def show @user = User.find(params[:id]).decorate end endapp/views/users/show.html.erb<%= @user.full_name %> <%= @user.full_name_kana %>Validator(バリデーター)
【例】
app/models/article.rbclass Article < ActiveRecord::Base validates :url, format: { with: /\A#{URI::regexp(%w(http https))}\z/ } endapp/models/products.rbclass Article < ActiveRecord::Base validates :url, format: { with: /\A#{URI::regexp(%w(http https))}\z/ } endモデルの役割の一つにバリデーションがあります。バリデーションとはデータの整合性を保つために、データを検証する機能のことです。
あるモデルのバリデーションに複雑な処理があったり、複数のモデルに共通のバリデーションが存在する場合にはそれらをモデルから切り離すことでリファクタリングが可能になります。
【例】app/models/articles.rbclass Article < ActiveRecord::Base validates :name, url_format: true endapp/models/products.rbclass Article < ActiveRecord::Base validates :url, url_format: true endapp/validators/url_format_validator.rbclass UrlFormatValidator < ActiveModel::EachValidator def validate_each(record, attribute, value) if value.present? && value !~ /\A#{URI::regexp(%w(http https))}\z/ record.errors[attribute] << "のフォーマットが不正です" end end end上の例ではActiveModel::EachValidatorを継承したクラスの中にvalidate_eachというメソッドを定義しています。このクラスのファイル名から_validatorを取り除いたものを各クラスのvalidatesメソッドに引数として渡すと、そのカラムを検証する際にvalidate_eachメソッドが実行されます。
また、様々な属性値に対して複雑な検証を行う場合などには以下のような方法もあります。
【例】app/models/event.rbclass event < ActiveRecord::Base validates_with RangeValidator endapp/validators/range_validator.rbclass RangeValidator < ActiveModel::Validator def validate(record) unless start_time < finish_time record.errors.add :base, "finish_timeはstart_timeよりも後に設定してください。" end end endCallback(コールバック)
【例】
class BankAccount < ActiveRecord::Base before_save EncryptionWrapper.new after_save EncryptionWrapper.new after_initialize EncryptionWrapper.new end class EncryptionWrapper def before_save(record) record.credit_card_number = encrypt(record.credit_card_number) end def after_save(record) record.credit_card_number = decypt(record.credit_card_number) end def after_initialize(record) record.credit_card_number = decypt(record.credit_card_number) end private def encrypt(value) # 暗号化の処理 end def decrypt(value) # 解読の処理 end endコントローラ同様にモデルにもvalidationの直前に実行されるbefore_validationであったり、saveの直後に実行されるafter_saveなど様々なタイミングで実行されるコールバックが存在します。
開発が大規模になるとコールバックにたくさんのメソッドが登録され、メソッド同士の関係性がわかりづらくなっていくことがあります。
そのようなときには、callbackの引数に、そのコールバックと同名のメソッドを持つインスタンスを渡すことで、コールバックの処理を別のクラスに移動することができます。
この例ではbefore_saveでクレジットカードナンバーを暗号化し、after_initialize, after_saveで解読を行っています。このようにコールバック同士に関係性がある場合には別の一つのクラスとして扱うことによって関係性を明確にすることができます。
- 投稿日:2020-04-06T11:56:35+09:00
Rails 日付、時間入力のヘルパーメソッド 6種類
環境
・OS
Vagrant + Ubuntu 16.04.5 LTS・言語
Rails 5.2.4.2
Ruby 2.5.1p57・gem
Bootstrap4
slim紹介
Railsで用意されている、日付、時間入力に関するヘルパーメソッドを6種類の紹介。
大きく、xxxx_selectと、xxxx_fieldと2種類あります。○ xxxx_select
xxxx_selectは、年、月、日と各項目ごとにテキストフィールドが分割されます。また、カレンダー入力はできなく、プルダウンメニューから選択する事になります。
data_select
.form-group = f.label :created_at, class: 'control-label' = f.date_select :created_at, class: 'form-control'time_select
= f.label :created_at, class: 'control-label' = f.time_select :created_at, class: 'form-control'datetime_select
.form-group = f.label :created_at, class: 'control-label' = f.datetime_select :created_at, class: 'form-control'○ xxxx_field
xxxx_fieldは、年、月、日等のテキストフィールドが1つにまとまっており、カレンダー入力ができるようになっています。こっちの方がモダン?
date_field
.form-group = f.label :created_at, class: 'control-label' = f.date_field :created_at, class: 'form-control'time_field
.form-group = f.label :created_at, class: 'control-label' = f.time_field :created_at, class: 'form-control'datetime_field
.form-group = f.label :created_at, class: 'control-label' = f.datetime_field :created_at, class: 'form-control'補足
横並びにしたい場合は、.form-inlineをつけます。.text-leftをつけると左寄りになって、ラベル位置が上下の項目と揃います。
.form-inline.text-left .form-group = f.label :created_at, '登録日 ', class: 'control-label' = f.date_field :created_at, class: 'form-control' .form-group = f.label :created_at, ' 登録時間 ', class: 'control-label' = f.time_field :created_at, class: 'form-control'
- 投稿日:2020-04-06T09:13:10+09:00
【AWS】Elastic IP解放→割り当て後に必要な事
この記事は?
AWSのElastic IP(以降EIP)再割り当て時の対応に関する記事です。
想定する読み手
- AWSでのデプロイ経験が乏しい方
- AWSでデプロイしたアプリを使わないからインスタンス停止、IP解放した方
- EIPを再割り当てしたけどアプリが起動できない方
著者開発環境
mac
Ruby 2.5.1
Rails 5.2.3
AWS
nginx
mySQL
unicornそもそもElastic IPとは
AWSで取得できる、アプリへアクセスするためのIPアドレスです。
特定のIPアドレスを指定することはできませんが、ランダムで取得したEIPは、解放※しない限り占有する事ができます。
(※解放:インスタンスに紐付けしているEIPの占有を解除する事)使用料金
起動中のEC2インスタンスに割り当てたEIPは無料(1インスタンスにつき1つ。2つ目以降は有料)で使用できます。
停止中インスタンスに割り当てられているEIPは有料。(0.005ドル/1時間)
インスタンスを停止していると1ヶ月で、0.005ドル×24(時間)×30(日) = 3.6ドルかかります。
日本円で400円くらいでしょうか。著者は使用しないアプリがあったのでインスタンスを停止していたのですが、AWSから請求があった事を知り、EIPを解放しました。
が、訳あって久しぶりにアプリの挙動を本番環境で確認するべく、停止していたインスタンスを起動し再度EIPを割り当てました。
すると、アプリが起動しなかった訳なんです。EIP再割り当て時に必要なことって?
結論、必要な対応は以下の2点でした。
- 本番環境nginx設定内部でelasticIPの書き換え
- ローカル環境config/deploy/production.rb内のelasticIP書き換え
考えてみれば当然の事なんですが、デプロイ時にEIPを記載していた箇所がありました。
そこのEIPを新しく割り当てたEIPに書き換える必要がある、という事ですね。実際にやった事
本番環境nginx設定内部でelasticIPの書き換え
本番環境にて、nginxの設定画面を開きます。
デイレクトリは自身のアプリのディレクトリです。ターミナル[ec2-user@ip-xxx-xx-xx-xx アプリ名]$ sudo vim /etc/nginx/conf.d/rails.conf以下のような画面が開くはずです。
ターミナルserver { listen 80; server_name 52.68.124.79; #ここを書き換え root /var/www/アプリ名/current/public; location ^~ /assets/ { gzip_static on; expires max; add_header Cache-Control public; root /var/www/アプリ名/current/public; } try_files $uri/index.html $uri @unicorn; location @unicorn { proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; proxy_set_header Host $http_host; proxy_redirect off; proxy_pass http://app_server; } error_page 500 502 503 504 /500.html; location = /favicon.ico { log_not_found off; } }この中のserver_nameという箇所がEIPを記載する箇所なので、ここを新しいEIPに書き換えます。
ローカル環境config/deploy/production.rb内のelasticIP書き換え
これは読んで字の如くなので割愛しますが、
config/deploy/production.rb内にもEIPを記載している箇所がありますので、そちらも新しいEIPに書き換えます。以上の対応で著者のアプリは久々に起動できました。
おわりに
今回の記事は、読む方をかなり限定するかもしれませんが、それでも誰かのお役に立てれば嬉しいです。
- 投稿日:2020-04-06T07:16:40+09:00
Sass::SyntaxError - File to import not found or unreadable: modules/ファイル名. の解決策
ポートフォリオを1から作っていると抜けて落ちている知識に
気がつくので、備忘録として投稿させて頂きます。application.scssの設定をチェック
Scssを導入したがパーシャル(分割したSassファイル)の設定が上手く行かず
Sass::SyntaxError - File to import not found or unreadable: modules/tasks.とターミナルで表示される。
app/assets/stylesheets/application.scss
@import "modules/tasks";この記述が悪さをしている。
原因を調査していると
stylesheetsフォルダの中に作成したたmodulesフォルダの名称が
modules.scssという名称になっていた為、
SyntaxError(構文エラー)が出ていたようです。フォルダ名をmodules.scss→modules 変更。
無事、解決しました。
- 投稿日:2020-04-06T03:58:38+09:00
(初学者) [Rails6] form_with に classを追記する
bootstrapを導入してからレコードの編集も新規追加もできなくなってしまった。
→ 原因は、フォームのところで<form>
タグと<%= form_with %>
が重複していたから。edit.html.erb<form class="form-horizontal" > ← ここと <%= form_with model: @article do |form| %> <%= form.text_field :title %> <%= form.submit 'Update' %> <% end %> </form> ← ここを消すと治った。では
class
はどこに書けばよいのか。
form_with
の<%= %>
内にclass
を書きたい。
→do
の手前に書く。edit.html.erb<%= form_with model: @article, class: "form-horizontal" do |form| %>
- 投稿日:2020-04-06T02:10:53+09:00
[devise]パスワード入力不要のユーザー編集
deviseを使用したユーザー情報の編集で、バスワード入力を省略する
手順 3つ
1. deviseコントローラファイルの作成(routes.rbの編集)
2. registrations_controller.rbの編集
3. edit.html.erbの編集1.deviseコントローラファイルの作成(routes.rbの編集)
deviseのコントローラを編集するため、以下を行ってください。
ターミナル$ rails g devise:controllers users ①コマンド実行で作成されるファイル Running via Spring preloader in process ***** create app/controllers/users/confirmations_controller.rb create app/controllers/users/passwords_controller.rb create app/controllers/users/registrations_controller.rb create app/controllers/users/sessions_controller.rb create app/controllers/users/unlocks_controller.rb create app/controllers/users/omniauth_callbacks_controller.rb =============================================================================== ②追加でroutes.rbに以下のような記述が必要なことをお知らせしてくれている Some setup you must do manually if you haven't yet: Ensure you have overridden routes for generated controllers in your routes.rb. For example: ⬇︎ 追記内容 ⬇︎ Rails.application.routes.draw do devise_for :users, controllers: { sessions: 'users/sessions' } end =============================================================================== 補足) このコマンドを実行しない限り中身をみることはできませんが、ユーザー登録時やサインイン時などは上記のコントローラで処理をしています。上記の指示に習って、routes.rbを編集します。
config/routes.rb# before Rails.application.routes.draw do devise_for :users # after Rails.application.routes.draw do devise_for :users, controllers: { registrations: "users/registrations", } # 今回は”編集”に関することなので、registrations_controllerのみ記述しています。2. registrations_controller.rbの編集
パスワードなしで編集できるように登録(編集)時に処理を行うコントローラの記述を変更します。ファイル下部の
protected
のコメントアウトを外したうえで、その下にupdate_resourceメソッド
を追記してください。registrations_controller.rb# コメントアウト外す protected #必須 更新(編集の反映)時にパスワード入力を省く def update_resource(resource, params) resource.update_without_password(params) end #任意 更新後のパスを指定 def after_update_path_for(resource) user_path(@user.id) endこれで更新時にパスワードを入力しなくてもよくなりました。
ただ編集画面にパスワードの入力欄が残ったままなので、もう少し変更を加えます。3. edit.html.erbの編集
最後に編集画面からパスワード入力欄をなくします。
まずはdeviseのビューを編集できるようにするため、以下を行ってください。ターミナル$ rails g devise:views Running via Spring preloader in process ***** ==== 必要な部分以外省略 ==== create app/views/devise/registrations/edit.html.erb続いてビューからパスワード欄の記述を削除します。
devise/registrations/edit.html.erb# 以下の記述を削除 <div class="field"> <%= f.label :password %> <i>(leave blank if you don't want to change it)</i><br /> <%= f.password_field :password, autocomplete: "new-password" %> <% if @minimum_password_length %> <br /> <em><%= @minimum_password_length %> characters minimum</em> <% end %> </div> <div class="field"> <%= f.label :password_confirmation %><br /> <%= f.password_field :password_confirmation, autocomplete: "new-password" %> </div> <div class="field"> <%= f.label :current_password %> <i>(we need your current password to confirm your changes)</i><br /> <%= f.password_field :current_password, autocomplete: "current-password" %> </div>以上で変更作業は終了です。
最後に動作確認を行いましょう。動作確認
今回は変更後の様子を分かりやすくするため、更新後に遷移する詳細ページのビューを以下のようにしています。ユーザー情報に
nickname
も追加しています。事前に登録した内容
nickname: sample
email: sample@sample
pasword: ******ユーザー詳細ページ
登録編集画面は以下のようになっています。
ユーザー登録編集ページ
パスワードの入力欄がすべてなくなっていますね。
それではユーザー情報を更新してみましょう。
nicknameをテストユーザー
に変更し、update
ボタンを押します。
すると、、、変更内容
nickname: sample => テストユーザー
ユーザー詳細ページ(更新後)
名前が
sample
からテストユーザー
に変わりましたね。
以上で終了となります。お疲れ様でした。
また最後までお読みいただきありがとうございました。補足
補足1)3. edit.html.erbの編集で任意事項(更新後にユーザー詳細ページへ遷移する)を記述した方は、変数
@user
を使用するため、usersコントローラのshowアクションで以下のように定義しておく必要があります。controllers/users_controller.rbdef show @user = User.find(params[:id]) end補足2)ユーザー詳細ページのコードは以下の通りです。同じshowアクションを使い、リンクによってマイページと他ユーザーのページが切り替わるようにしてあります。
users/show.html.erb#マイページの記述 <% if params[:id].nil? || @user.id == current_user.id %> <h1>ようこそ<%= current_user.nickname %>さん</h1> ここはusers#showページです。 <p>名前:<%= current_user.nickname %></p> <p>登録email:<%= current_user.email %></p> <br> アカウントを編集しますか? <%= link_to "はい", edit_user_registration_path %> <br> ログアウトしますか? <%= link_to "はい", destroy_user_session_path, method: :delete %> #他ユーザーページ記述 <% else %> <h2>ここは<%= @user.nickname %>さんのページです</h2> <p>名前:<%= @user.nickname %></p> <p>登録email:<%= @user.email %></p> <% end %>
- 投稿日:2020-04-06T00:07:26+09:00
Rails入門メモ1
コマンド
Railsアプリケーション作成
$rails new アプリケーション名
実行すると新しいファイルが作成される。
ファイルの中でも「app」「config」「db」が重要。appの中にはasset(画像やJavaScriptやCSS)、controller、view(HTML)、model(DBを操作する奴)がある。
configの中にはrouteがある。ページ作成
$rails generate controller コントローラー名 アクション名
#例 rails generate controller home top #省略版 rails g controller home top実行すると、localhost:3000/home/topというURLにアクセス出来る。
また、viewフォルダの中にhomeフォルダとtop.html.erbファイルが出来る。ページ作成
3つの要素を必要とする。Rails中に存在する。
●ビュー(view)
html.erbファイルをもつ。
●コントローラー(controller)
例)homeコントローラーのtopアクションに対応するHTMLをビューから探してブラウザに渡す。
また、ビューのHTMLで使用する変数は、コントローラーのアクション内で宣言できる。
●ルーティング(routing)
URLとそれに対応するコントローラーとアクション情報のテーブルをもつ。流れ
ブラウザがRailsにHTMLファイルを要求すると、Rails中のルーティングに記載されているURLを見て、それに対応するコントローラーを経由してビューをブラウザに返す。
☆新しいページを追加するには、自分でルーティングやコントローラー(アクション)を記述する。
参考文献
Progate https://prog-8.com/languages/rails5
ドットインストール https://dotinstall.com/lessons/basic_rails_v3