20200406のRailsに関する記事は19件です。

【Rails】whenever によるバッチ処理(runner編)

はじめに

whenever が使いやすいと書かれていたにもかかわらず、少しはまってしまったのでまとめます。
特に、runner について書きたいと思います。

GemFile

GemFile に whenever を追記して bundle install

GemFile
gem 'whenever', :require => false
$ bundle install

自動化したいソースを記述

と、その前に準備があります。
config/application.rb に 以下の1行を追記してください。
lib のディレクトリの内容を反映させるようです。

ここがはまってしまったポイントです。

config/application.rb
class Application < Rails::Application
  # 追記
  config.autoload_paths += Dir["#{config.root}/lib"]
end

lib/batch/hoge.rb に自動化したいソースを記述してください。

lib/batch/hoge.rb
class 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.rb
set :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 を使ったバッチ処理反映方法でした。
少しでも参考になる方がいれば嬉しいです。

参考

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Ruby】【短期】Qiitaの読んでおかなければいけない記事100選【毎日自動更新】

ページ容量を増やさないために、不具合報告やコメントは、説明記事 に記載いただけると助かります。

順位 記事名
________________________________________
ユーザ 投稿日付
更新日付
LGTM1
1 (下準備編)世界一丁寧なAWS解説。EC2を利用して、RailsアプリをAWSにあげるまで naoki_mochizuki 16/01/08
19/01/17
2591
166
2 プログラミング勉強を加速させる7つの習慣 YudaiTsukamoto 16/12/15
16/12/21
2933
69
3 高校文化祭の食販で自動注文機を作った話 RyotaroSaito 19/11/15
19/12/22
1304
10
4 一番詳しいCSS設計規則BEMのマニュアル Takuan_Oishii 17/08/30
19/07/16
787
153
5 【初心者向け】丁寧すぎるRails『アソシエーション』チュートリアル【幾ら何でも】【完璧にわかる】? kazukimatsumoto 18/11/29
19/12/06
711
162
6 未経験からRuby on Railsを学んで仕事につなげるまでの1000時間メニュー saboyutaka 18/12/09
19/09/14
1178
55
7 【初心者向け】テストコードの方針を考える(何をテストすべきか?どんなテストを書くべきか?) jnchito 18/05/22
18/06/14
1173
75
8 使えるRSpec入門・その1「RSpecの基本的な構文や便利な機能を理解する」 jnchito 14/10/26
19/07/22
2924
0
9 【まつもとゆきひろ氏 特別講演】20代エンジニアのためのプログラマー勉強法のまとめ 2019/3/30 motoki4917 19/03/30
19/10/19
1642
31
10 [Rails] deviseの使い方(rails5版) cigalecigales 16/11/13
18/05/17
852
59
11 非デザイナーエンジニアが一人でWebサービスを作るときに便利なツール32選 okappy 14/09/18
15/07/08
6312
0
12 Railsアプリケーションにおけるエラー処理(例外設計)の考え方 jnchito 15/09/28
20/02/03
1557
68
13 Rails deviseで使えるようになるヘルパーメソッド一覧 tobita0000 17/05/07
17/05/07
488
62
14 Railsで超簡単API k-penguin-sato 18/06/27
20/02/24
387
59
15 Rails開発におけるwebサーバーとアプリケーションサーバーの違い(翻訳) jnchito 15/10/20
15/10/21
1223
35
16 削除済(ID:b1aa2ae143624e551aea) saitoeku3 18/06/18
19/07/05
299
55
17 Rails5.2から追加された credentials.yml.enc のキホン NaokiIshimura 18/04/12
18/04/13
413
44
18 Rails における内部結合、外部結合まとめ yuyasat 16/09/03
19/01/14
574
45
19 プログラミング初心者歓迎!「エラーが出ました。どうすればいいですか?」から卒業するための基本と極意(解説動画付き) jnchito 16/06/26
19/05/01
1167
42
20 なぜrailsの本番環境ではUnicorn,Nginxを使うのか?  ~ Rack,Unicorn,Nginxの連携について ~【Ruby On Railsでwebサービス運営】 takahiro1127 18/05/13
19/11/13
268
74
21 「アプリケーションが壊れているのに検知できないテストコード」を書かないようにするための、べからず集 jnchito 20/01/29
20/02/09
528
528
22 (デプロイ編①)世界一丁寧なAWS解説。EC2を利用して、RailsアプリをAWSにあげるまで naoki_mochizuki 16/01/12
20/01/17
569
52
23 【これが無料?】無料で学べるプログラミング教材・ハンズオン一覧 kocpa 19/06/26
19/07/05
935
9
24 【Rails 5】(新) form_with と (旧) form_tag, form_for の違い hmmrjn 18/07/01
18/07/03
392
42
25 rails generate migrationコマンドまとめ zaru 14/09/09
18/11/06
1467
0
26 Ruby on Rails, Vue.js で始めるモダン WEB アプリケーション入門 tatsurou313 19/02/11
19/09/29
273
65
27 [初心者向け] RubyやRailsでリファクタリングに使えそうなイディオムとか便利メソッドとか jnchito 13/11/04
18/03/14
3008
0
28 未経験者には全てが黒魔術に見える呪いがある mackey0022 19/10/15
19/10/18
471
22
29 「Railsは終わった」と言われる理由 klriutsa 19/03/05
19/08/22
432
55
30 【Rails 5.2】 Active Storageの使い方 hmmrjn 18/06/30
19/08/06
338
42
31 VSCodeでRuby On Railsを快適に書きたい sensuikan1973 18/10/07
19/06/17
479
36
32 【爆速成長!】プログラミング駆け出し〜オリジナルポートフォリオ作成までに参考にしたサイト一覧 taku99 20/03/27
20/03/27
308
308
33 【Rails】MySQL2がbundle installできない時の対応方法 fukuda_fu 19/03/21
19/04/10
238
58
34 【サーバーサイド一式】Docker + Rails + Circle CI + Terraformでインフラをコードで環境構築 & ECSへ自動コンテナデプロイ【前半】 kazukimatsumoto 19/12/04
19/12/16
526
53
35 Railsバリデーションまとめ shunhikita 15/02/24
17/11/15
1037
0
36 Rubyによるデザインパターンまとめ yuji_ariyasu 18/09/10
19/08/15
525
33
37 Ruby on Rails カラムの追加と削除 azusanakano 16/03/29
16/03/29
310
43
38 [Docker] 初心者が知っておくと便利かもしれない18の知識 enta0701 17/09/30
19/01/17
376
29
39 gem installでpermissionエラーになった時の対応方法 nishina555 18/11/25
19/09/25
220
53
40 スタブとモックの違い k5trismegistus 17/04/05
17/04/06
361
33
41 Ruby on Rails 6の主要な新機能・機能追加・変更点 ryohashimoto 18/12/22
19/10/21
291
38
42 【初心者向け】RailsのActive Recordの解説&メソッドまとめ ryokky59 18/10/05
18/10/05
184
50
43 bundle install と bundle updateの違いについて lasershow 16/01/21
16/01/21
370
30
44 決定版!!Haml小技まとめ!! yukimura1227 16/04/16
18/11/29
293
34
45 find、find_by、whereの違い tsuchinoko_run 18/03/17
18/03/17
216
50
46 mysql2 gemインストール時のトラブルシュート HrsUed 18/11/28
19/04/16
264
24
47 ActiveRecordのjoinsとpreloadとincludesとeager_loadの違い k0kubun 14/09/04
16/02/11
1507
0
48 Rubyの文字列とシンボルの違いをキッチリ説明できる人になりたい Kta-M 16/09/05
19/04/07
441
27
49 Railsアプリで Bootstrap 4 を利用する NaokiIshimura 17/11/03
19/08/14
292
33
50 bundle install時に--path vendor/bundleを付ける必要性は本当にあるのか、もう一度よく考えてみよう jnchito 19/06/06
19/06/07
304
50
51 Rails で includes して N+1 問題対策 hirotakasasaki 17/02/10
17/02/11
321
31
52 [Ruby入門] 14. 日付と時刻を扱う(全パターン網羅) prgseek 17/04/28
17/05/05
289
35
53 Capybaraチートシート morrr 17/08/19
17/08/19
289
24
54 RailsアプリをDockerで開発するための手順 togana 16/04/11
17/07/31
684
25
55 railsのrenderとredirect_toの違い 1ulce 16/12/02
16/12/02
310
19
56 【Rails初心者必見!】ひたすら丁寧にデータ取得を説明(find, where) mr-myself 15/09/03
15/09/03
435
37
57 [Rails]ransackを利用した色々な検索フォーム作成方法まとめ nishina555 17/03/02
19/05/13
294
29
58 (DB・サーバー構築編)世界一丁寧なAWS解説。EC2を利用して、RailsアプリをAWSにあげるまで naoki_mochizuki 16/01/10
19/01/17
459
33
59 bundle install 時、mysql2でエラー tktcorporation 18/12/26
19/07/25
227
28
60 【まつもとゆきひろ氏 特別講演】若手エンジニアの生存戦略に行ってきたので私的メモ DAdDY0055 18/06/23
18/06/27
1244
3
61 あなたはいくつ知っている?Rails I18nの便利機能大全! Kta-M 17/06/26
19/04/19
350
26
62 並行処理、並列処理のあれこれ Kohei909Otsuka 18/02/14
18/02/15
215
31
63 【Rails】deviseを導入してみる Hal_mai 18/11/07
18/11/08
161
42
64 rspec-rails 3.7の新機能!System Specを使ってみた jnchito 17/10/23
19/12/14
362
23
65 Awesome Ruby : 素晴しい Ruby のライブラリ・ツール・フレームワーク・ソフトウェアの数々 hatai 17/07/24
19/11/01
550
15
66 Railsのjbuilderの書き方と便利なイディオムやメソッド ryouzi 17/11/28
19/01/08
274
24
67 忘れがちなrenderメソッドの使い方まとめ [Rails] hayashino 18/11/24
18/12/01
140
54
68 Rails の session を完全に理解した zettaittenani 18/12/17
19/07/16
184
31
69 Bundlerの使い方 oshou 16/03/27
17/02/03
387
20
70 N+1問題 TsubasaTakagi 17/12/07
17/12/07
188
32
71 モデルやメソッドに名前を付けるときは英語の品詞に気をつけよう jnchito 14/05/28
17/06/27
3076
0
72 Ruby on Rails+ReactでCRUDを実装してみた yoshimo123 18/02/17
19/02/28
240
26
73 Railsのポリモーフィック関連とはなんなのか itkrt2y 16/12/03
18/12/20
310
28
74 【2018年版】macにrbenvを入れてrubyを管理できるようにしちゃう Alex_mht_code 18/04/17
19/06/07
236
21
75 RubyとRailsにおけるTime, Date, DateTime, TimeWithZoneの違い jnchito 14/12/07
18/01/25
1425
0
76 Rails 5.2 で ActiveSupport::MessageEncryptor::InvalidMessage scivola 18/05/24
19/05/27
230
28
77 Webpacker使うなら最低限これだけは知っておいてほしいこと chimame 18/08/07
19/12/18
207
28
78 使えるRSpec入門・その2「使用頻度の高いマッチャを使いこなす」 jnchito 14/11/05
19/07/22
941
0
79 みんなRailsのSTIを誤解してないか!? yebihara 16/12/04
16/12/16
429
29
80 ニコニ立体を直した話 uproad3 19/11/07
19/12/02
230
0
81 Docker + Rails + Puma + Nginx + MySQL eighty8 17/08/25
19/10/28
174
35
82 あなたはDRY原則を誤認している? yatmsu 16/12/06
18/07/29
236
25
83 使えるRSpec入門・その4「どんなブラウザ操作も自由自在!逆引きCapybara大辞典」 jnchito 15/01/01
19/07/22
1096
0
84 Ruby 正規表現の使い方 shizuma 15/07/27
15/07/28
485
25
85 VSCode公式の機能で、リモートサーバにSSHして編集する【Insiders Preview】 suzuki_sh 19/05/03
19/05/12
372
18
86 永久保存版!?伊藤さん式・Railsアプリのアップグレード手順 jnchito 19/08/18
19/10/24
337
37
87 はじめてのRails API c5meru 17/12/16
17/12/16
296
18
88 20万pv/月達成のwebサービスのRailsソースコード、全部見せます! kent_ear 18/07/31
19/08/22
788
7
89 AWS:無料でSSL証明書を取得する方法 iwaseasahi 17/06/03
18/01/13
255
21
90 フロントエンド全然わからないマンが、ちょっとでも見た目のいいWebサービスを作ろうとしてやったこと liukoki 18/03/21
18/03/25
1018
15
91 RubyのModuleの使い方とはいったい shiopon01 16/09/15
16/09/15
264
25
92 Rails enumについてまとめておく shizuma 16/01/07
16/01/07
275
23
93 redirect_to @userが何を省略しているかわかりますか?〜挫折しないRailsチュートリアル7章〜 Kawanji01 18/07/05
20/03/16
168
43
94 実務で学んだRailsの設計・リファクタリング wawoon 17/12/08
19/02/10
203
27
95 あなたがマスターしたのはいくつ? Railsを習得するために必要な技術要素の一覧 jnchito 16/07/06
16/07/26
1175
17
96 railsで多対多のアソシエーションの作り方と、出来ること Kohei_Kishimoto0214 17/01/19
17/06/26
286
18
97 RailsアプリへのRspecとFactory_botの導入手順 Ushinji 18/01/08
19/12/14
208
23
98 [初学者]Railsのi18nによる日本語化対応 shimadama 18/07/31
20/03/22
153
35
99 docker-composeを爆速にする shotat 18/05/13
18/05/13
174
46
100 Railsのルーティングの種類と要点まとめ senou 16/05/20
19/02/05
229
24

  1. 1行目が総数。2行目が直近3ヵ月。 

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【Ruby】【長期】Qiitaの読んでおかなければいけない記事100選【毎日自動更新】

ページ容量を増やさないために、不具合報告やコメントは、説明記事 に記載いただけると助かります。

順位 記事名
________________________________________
ユーザ 投稿日付
更新日付
LGTM1
1 (下準備編)世界一丁寧なAWS解説。EC2を利用して、RailsアプリをAWSにあげるまで naoki_mochizuki 16/01/08
19/01/17
2591
913
2 プログラミング勉強を加速させる7つの習慣 YudaiTsukamoto 16/12/15
16/12/21
2933
471
3 使えるRSpec入門・その1「RSpecの基本的な構文や便利な機能を理解する」 jnchito 14/10/26
19/07/22
2924
343
4 非デザイナーエンジニアが一人でWebサービスを作るときに便利なツール32選 okappy 14/09/18
15/07/08
6312
308
5 一番詳しいCSS設計規則BEMのマニュアル Takuan_Oishii 17/08/30
19/07/16
787
560
6 [初心者向け] RubyやRailsでリファクタリングに使えそうなイディオムとか便利メソッドとか jnchito 13/11/04
18/03/14
3008
189
7 rails generate migrationコマンドまとめ zaru 14/09/09
18/11/06
1467
216
8 【初心者向け】丁寧すぎるRails『アソシエーション』チュートリアル【幾ら何でも】【完璧にわかる】? kazukimatsumoto 18/11/29
19/12/06
711
511
9 [Rails] deviseの使い方(rails5版) cigalecigales 16/11/13
18/05/17
852
254
10 未経験からRuby on Railsを学んで仕事につなげるまでの1000時間メニュー saboyutaka 18/12/09
19/09/14
1178
488
11 Railsアプリケーションにおけるエラー処理(例外設計)の考え方 jnchito 15/09/28
20/02/03
1557
242
12 Rails開発におけるwebサーバーとアプリケーションサーバーの違い(翻訳) jnchito 15/10/20
15/10/21
1223
203
13 【初心者向け】テストコードの方針を考える(何をテストすべきか?どんなテストを書くべきか?) jnchito 18/05/22
18/06/14
1173
319
14 Railsバリデーションまとめ shunhikita 15/02/24
17/11/15
1037
195
15 高校文化祭の食販で自動注文機を作った話 RyotaroSaito 19/11/15
19/12/22
1304
1304
16 【まつもとゆきひろ氏 特別講演】20代エンジニアのためのプログラマー勉強法のまとめ 2019/3/30 motoki4917 19/03/30
19/10/19
1642
462
17 Rails deviseで使えるようになるヘルパーメソッド一覧 tobita0000 17/05/07
17/05/07
488
274
18 プログラミング初心者歓迎!「エラーが出ました。どうすればいいですか?」から卒業するための基本と極意(解説動画付き) jnchito 16/06/26
19/05/01
1167
218
19 ActiveRecordのjoinsとpreloadとincludesとeager_loadの違い k0kubun 14/09/04
16/02/11
1507
149
20 Rails における内部結合、外部結合まとめ yuyasat 16/09/03
19/01/14
574
204
21 (デプロイ編①)世界一丁寧なAWS解説。EC2を利用して、RailsアプリをAWSにあげるまで naoki_mochizuki 16/01/12
20/01/17
569
203
22 モデルやメソッドに名前を付けるときは英語の品詞に気をつけよう jnchito 14/05/28
17/06/27
3076
119
23 Railsで超簡単API k-penguin-sato 18/06/27
20/02/24
387
324
24 RubyとRailsにおけるTime, Date, DateTime, TimeWithZoneの違い jnchito 14/12/07
18/01/25
1425
118
25 使えるRSpec入門・その2「使用頻度の高いマッチャを使いこなす」 jnchito 14/11/05
19/07/22
941
140
26 使えるRSpec入門・その4「どんなブラウザ操作も自由自在!逆引きCapybara大辞典」 jnchito 15/01/01
19/07/22
1096
127
27 Rails5.2から追加された credentials.yml.enc のキホン NaokiIshimura 18/04/12
18/04/13
413
236
28 脱初心者を目指すVimmerにオススメしたいVimプラグインや.vimrcの設定 jnchito 14/06/08
18/05/15
1938
82
29 RailsアプリをDockerで開発するための手順 togana 16/04/11
17/07/31
684
88
30 Ruby on Rails カラムの追加と削除 azusanakano 16/03/29
16/03/29
310
163
31 【Rails 5】(新) form_with と (旧) form_tag, form_for の違い hmmrjn 18/07/01
18/07/03
392
239
32 bundle install と bundle updateの違いについて lasershow 16/01/21
16/01/21
370
143
33 スタブとモックの違い k5trismegistus 17/04/05
17/04/06
361
165
34 削除済(ID:b1aa2ae143624e551aea) saitoeku3 18/06/18
19/07/05
299
260
35 Rubyの文字列とシンボルの違いをキッチリ説明できる人になりたい Kta-M 16/09/05
19/04/07
441
136
36 【Rails初心者必見!】ひたすら丁寧にデータ取得を説明(find, where) mr-myself 15/09/03
15/09/03
435
121
37 【Rails 5.2】 Active Storageの使い方 hmmrjn 18/06/30
19/08/06
338
218
38 [Docker] 初心者が知っておくと便利かもしれない18の知識 enta0701 17/09/30
19/01/17
376
197
39 使えるRSpec入門・その3「ゼロからわかるモック(mock)を使ったテストの書き方」 jnchito 14/11/21
15/09/29
969
109
40 VSCodeでRuby On Railsを快適に書きたい sensuikan1973 18/10/07
19/06/17
479
225
41 なぜrailsの本番環境ではUnicorn,Nginxを使うのか?  ~ Rack,Unicorn,Nginxの連携について ~【Ruby On Railsでwebサービス運営】 takahiro1127 18/05/13
19/11/13
268
234
42 決定版!!Haml小技まとめ!! yukimura1227 16/04/16
18/11/29
293
156
43 【これが無料?】無料で学べるプログラミング教材・ハンズオン一覧 kocpa 19/06/26
19/07/05
935
935
44 Rubyで%記法(パーセント記法)を使う mogulla3 14/08/23
14/08/23
903
86
45 Bundlerの使い方 oshou 16/03/27
17/02/03
387
121
46 「Railsは終わった」と言われる理由 klriutsa 19/03/05
19/08/22
432
280
47 railsのrenderとredirect_toの違い 1ulce 16/12/02
16/12/02
310
150
48 (DB・サーバー構築編)世界一丁寧なAWS解説。EC2を利用して、RailsアプリをAWSにあげるまで naoki_mochizuki 16/01/10
19/01/17
459
136
49 nil? empty? blank? present? の使い分け somewhatgood@github 13/01/24
13/01/24
1084
100
50 Rails で includes して N+1 問題対策 hirotakasasaki 17/02/10
17/02/11
321
129
51 Ruby on Rails, Vue.js で始めるモダン WEB アプリケーション入門 tatsurou313 19/02/11
19/09/29
273
266
52 Awesome Ruby : 素晴しい Ruby のライブラリ・ツール・フレームワーク・ソフトウェアの数々 hatai 17/07/24
19/11/01
550
110
53 Rubyによるデザインパターンまとめ yuji_ariyasu 18/09/10
19/08/15
525
170
54 [Rails]ransackを利用した色々な検索フォーム作成方法まとめ nishina555 17/03/02
19/05/13
294
144
55 [Ruby入門] 14. 日付と時刻を扱う(全パターン網羅) prgseek 17/04/28
17/05/05
289
146
56 早く知ってたら良かったrailsの技 k-shogo 14/12/18
14/12/18
1125
75
57 Ruby 正規表現の使い方 shizuma 15/07/27
15/07/28
485
117
58 Capybaraチートシート morrr 17/08/19
17/08/19
289
145
59 Railsアプリで Bootstrap 4 を利用する NaokiIshimura 17/11/03
19/08/14
292
146
60 あなたがマスターしたのはいくつ? Railsを習得するために必要な技術要素の一覧 jnchito 16/07/06
16/07/26
1175
98
61 【Rails】form_for/form_tagの違い・使い分けをまとめた shunsuke227ono 15/04/28
16/11/15
834
71
62 Ruby block/proc/lambdaの使いどころ kidach1 13/11/18
17/01/29
1427
83
63 あなたはいくつ知っている?Rails I18nの便利機能大全! Kta-M 17/06/26
19/04/19
350
127
64 知識0から、AWSのEC2でウェブサーバーを構築するまで shunsuke227ono 15/10/26
16/04/24
461
97
65 Railsのポリモーフィック関連とはなんなのか itkrt2y 16/12/03
18/12/20
310
104
66 中規模Web開発のためのMVC分割とレイヤアーキテクチャ yuku_t 14/05/20
17/08/15
1725
67
67 みんなRailsのSTIを誤解してないか!? yebihara 16/12/04
16/12/16
429
101
68 【まつもとゆきひろ氏 特別講演】若手エンジニアの生存戦略に行ってきたので私的メモ DAdDY0055 18/06/23
18/06/27
1244
10
69 Rails enumについてまとめておく shizuma 16/01/07
16/01/07
275
106
70 【初心者向け】これからRailsエンジニアとして成長したい人がすべきこと hc0208 16/03/21
18/10/15
356
103
71 Ruby on Rails 6の主要な新機能・機能追加・変更点 ryohashimoto 18/12/22
19/10/21
291
217
72 【Rails】MySQL2がbundle installできない時の対応方法 fukuda_fu 19/03/21
19/04/10
238
236
73 俺が悪かった。素直に間違いを認めるから、もうサービスクラスとか作るのは止めてくれ joker1007 16/12/15
17/01/08
945
84
74 RubyのModuleの使い方とはいったい shiopon01 16/09/15
16/09/15
264
107
75 rspec-rails 3.7の新機能!System Specを使ってみた jnchito 17/10/23
19/12/14
362
137
76 Railsのjbuilderの書き方と便利なイディオムやメソッド ryouzi 17/11/28
19/01/08
274
139
77 railsで多対多のアソシエーションの作り方と、出来ること Kohei_Kishimoto0214 17/01/19
17/06/26
286
103
78 gem installでpermissionエラーになった時の対応方法 nishina555 18/11/25
19/09/25
220
202
79 ノンプログラマーが3ヶ月でWebサービスを作ってみた tabbyz 15/02/25
16/03/27
1597
56
80 あなたはDRY原則を誤認している? yatmsu 16/12/06
18/07/29
236
110
81 Railsのルーティングの種類と要点まとめ senou 16/05/20
19/02/05
229
103
82 mysql2 gemインストール時のトラブルシュート HrsUed 18/11/28
19/04/16
264
211
83 Ruby のエラーメッセージを読み解く(初心者向け)その 1 scivola 16/03/05
19/08/06
256
106
84 日本正式リリースしたStripeを使ってサブスクリプション型決済システムを実装する tady 16/10/04
18/05/21
394
92
85 find、find_by、whereの違い tsuchinoko_run 18/03/17
18/03/17
216
148
86 はじめてのRails API c5meru 17/12/16
17/12/16
296
116
87 フロントエンド全然わからないマンが、ちょっとでも見た目のいいWebサービスを作ろうとしてやったこと liukoki 18/03/21
18/03/25
1018
83
88 YAMLとは何か? - いつもRailsの設定ファイルで出てくるやつの正体 Yama-to 15/07/27
15/08/08
385
96
89 20万pv/月達成のwebサービスのRailsソースコード、全部見せます! kent_ear 18/07/31
19/08/22
788
60
90 Rubyのメソッドの引数受け渡しまとめ raccy 16/07/17
19/12/25
233
112
91 (Capistrano編)世界一丁寧なAWS解説。EC2を利用して、RailsアプリをAWSにあげるまで naoki_mochizuki 16/02/01
19/11/14
301
100
92 Ruby on RailsのAjax処理のおさらい ka215 15/01/20
19/06/25
728
77
93 AWS:無料でSSL証明書を取得する方法 iwaseasahi 17/06/03
18/01/13
255
118
94 Rails 5 + ActionCableで作る!シンプルなチャットアプリ(DHH氏のデモ動画より) jnchito 15/12/22
16/07/13
644
78
95 今更聞けないpryの使い方と便利プラグイン集 k0kubun 14/12/21
16/01/16
752
60
96 並行処理、並列処理のあれこれ Kohei909Otsuka 18/02/14
18/02/15
215
141
97 正規表現のパフォーマンスの話をされても全くピンと来なかった僕は、backtrackに出会いました。 mochizukikotaro 16/05/28
17/04/04
539
35
98 最速!MacでRuby on Rails環境構築 narikei 15/12/12
19/03/05
318
77
99 Ruby on Rails+ReactでCRUDを実装してみた yoshimo123 18/02/17
19/02/28
240
125
100 【初心者向け】RailsのActive Recordの解説&メソッドまとめ ryokky59 18/10/05
18/10/05
184
175

  1. 1行目が総数。2行目が直近1年。 

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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ビューという基本を守った方が良い。
その場合、実装方法には様々な方法があるため、色々試して見るとより理解が深まるかもしれません。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Rails ウィザード形式導入について 3

はじめに

Rails ウィザード形式導入について 1 はこちらをクリック願います。
Rails ウィザード形式導入について 2 はこちらをクリック願います。
チーム開発でフリマサイトを開発致しました。
その際、ユーザーの新規登録画面でウィザード形式を導入致しましたので、内容を整理します。
もうすでにご存知の方、省略の仕方等ご存知でしたら、ご教授願います。

前提

  • ユーザー情報(User)については 以下 A と記述します。
  • 住所情報(Destination)については 以下 B と記述します。

Bの登録の各アクション(create)とビュー(new,create)

ルーティング設定(new,create)

  • B情報を登録するページを表示するnew_destinationアクションのルーティングを設定します。
  • また、B情報を登録するcreate_destinationアクションのルーティングも設定します。
config/routes.rb
Rails.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"
end

B情報のビューファイルの作成(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.rb
class 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

  # 省略
end

2ページ目で入力した住所情報のバリデーションチェック
  • 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かと!

さいごに

日々勉強中ですので、随時更新します。
皆様の復習にご活用頂けますと幸いです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【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)

最終目標

最終的にできて欲しいのは以下。

  1. 検索ボックスにキーワードを入力する
  2. キーワードに基いた検索結果が投稿フォームの下に表示される

そのために必要な処理

  1. 検索フォームにキーワードを入力
  2. キーワードをコントローラ側で受け取る
  3. 受け取ったキーワードを元にAPIを叩く
  4. 叩かれたAPIから情報を取得する
  5. 取得した情報を投稿画面に渡す
  6. 渡された情報で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.rb
module 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
end

get_urlは引数にkeywordが設定されており、画面から入力されたパラメータを受け取ってAPIの#{keyword}部分に渡されます。

HTTParty.get(url)でAPIを叩いて情報を取得します。
このHTTPartyは、自動でjsonを解析してrubyのhashに変換してくれる優れもの。

#api関連
gem 'json'
gem 'httparty'

gemをインストールしときましょう。

コントローラーに取得した情報を渡す

検索フォームから受け取ったパラメーターを先ほど作成したモジュールを経由してAPIを叩き、コントローラーで取得します。

posts_controller.rb
require '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.rb
def url_from_keyword
    keyword = params[:keyword]
    BooksApi.get_url(keyword)
end

これはパラメーターを受け取って、その情報を先ほど作成したモジュールに引数で渡してAPIの情報を取得する処理を行っています。

しかし、フォームから送信するパラメーターを直接ここに投げるわけではありません。

それが先ほどのmethod:getの話につながります。

newアクション

posts_controller.rb
def new
  if @results.present?
     @post = Post.new
  else
     @post = Post.new
     @results = url_from_keyword
  end
end

newアクションではAPIの情報があるときとない時で処理を分けています。

ない時は@rersultsに初期値で空配列を入れており、処理はPost.newだけです。

APIが叩かれた場合はその情報を@resultsに入れてるので、Post.newと@resultsの情報の表示処理を行います。

先ほど検索フォームを作成した際、methodをgetに設定していたのはこのためです。

routes.rb
resources :posts do
    post 'add' => 'likes#create'
    delete '/add' => 'likes#destroy'
end

newアクションは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は以前書いたいいね機能とほとんど同じです。

【Rails】いいね機能の実装

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.rb
class NilClass
    def [](*)
      nil
    end
end
posts_controller.rb
class PostsController < ApplicationController
    @results = []
    require 'nil_class'
...

モジュールを作ったディレクトリにnilclass用のファイルを作り、それをrequireで呼び出してます。

これでとりあえず表示は問題ないです。

まとめ

今回このポートフォリオを作る中で結構ミソのとこではあったので、自分なりに色々がんばりました。

ぶっちゃけコードは美しくないのでそこはこれから改善したいと思います…。

ひとまず作品自体は大体完成したので、あとはデプロイだけです。

が、AWSのデプロイが全然できなくて絶賛躓き中でございます。

無事デプロイが完了しましたらその辺の奮闘記も書きたいと思いますので、その時はどうぞよろしくお願い致します。

ではでは。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Railsにおける例外処理

rails db:seed

rails db:seedコマンドは、db/seeds.rbの記述に基づいて、データベースにレコードを作成するコマンドです。
クローン直後に投入したい初期データがある場合に利用します。
ターミナル

# 初期データの投入
$ rails db:seed

【例】チケット販売を例とします

db/seeds.rb
users = []
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 ドキュメント(英語)

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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へ接続する時に使う環境変数が文字列に変換されてしまっているのだろう。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

Rails Consoleでselect文などを記述する

メモ

ActiveRecord::Base.connection.select_all("select * from users").to_hash

めちゃくちゃ参考になる記事
https://qiita.com/yut_h1979/items/4cb3d9a3b3fc87ca0435

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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.rb
class 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.rb
class TasksController < ApplicationController

  def index
    @task = Task.new
    # モデルに定義したscopeはメソッドのように呼び出せる
    @tasks = Task.incoming.order(start_at: :asc)
  end

# 以下省略

参考リンク

enumリファレンス(英語)
enum_help Githubリポジトリ
Rails ModelのScope(スコープ)の使い方

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

素人が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/)

  

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

MVCのリファクタリング

ビューのリファクタリング

ビューファイルで複雑な呼び出しを行っている場合

【例】

app/views/articles/index.html.erb
<% Article.where(status: 1).order(likes_count: :desc).limit(10).each do |article| %>
  <%= article.title %>
<% end %>

この例では「表示処理を行う」ことを責務としたビュー上で、データの呼び出しに関する複雑な処理が書かれています。
このような複雑な処理は、「データ処理を行う」ことを責務としたモデルに記載します。なぜかというとビューファイルに複雑な記述があると、コードの視認性が悪くなります。また、モデルに記述すると、様々なアクションで用いることができます。
また、モデルに定義した処理を行った上で、コントローラでインスタンス変数として定義します。
model

class Article < ActiveRecord::Base
  scope :popular, -> { order(likes_count: :desc) }
  enum status: { draft: 0, published: 1 }
end

controller

def index
  @articles = Article.published.popular.limit(10)
end

view

<% @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.rb
def current_user_has?(instance)
  user_signed_in? && current_user == instance.user
end
app/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ではビューで使えるヘルパーメソッドが使用できます。
helper

def 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
end

view

<%= 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.rb
class 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
end
app/controllers/top_controller.rb
class 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.rb
module 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
end
app/controllers/products_controller.rb
class ProductsController < ApplicationController
  include CurrentCart
  before_action :set_cart
end
app/controllers/top_controller.rb
class TopController < ApplicationController
  include CurrentCart
  before_action :set_cart
end

ユーザーのカート情報を扱うためにそれぞれのコントローラでこのset_cartを定義する必要がありますが、定義したCurrentCartを使用したいコントローラで読み込むだけでそこに定義されているメソッドを使用することができるようになります。

複数のコントローラに同じ処理が記述されている場合(継承)

共通の処理を持つコントローラが同じ親コントローラを継承していれば、親コントローラに記述することで処理を共通化することができます。

app/controllers/sales_controller.rb
class SalesController < ApplicationController
  before_action :authorize_owner

  private

  def authorize_owner
    redirect_to root_path unless current_user.owner?
  end
end
app/controllers/customers_controller.rb
class 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.rb
def ApplicationController < ActionController::Base

  private

  def authorize_owner
    redirect_to root_path unless current_user.owner?
  end
end
app/controllers/sales_controller.rb
class SalesController < ApplicationController
  before_action :authorize_owner
end
app/controllers/customers_controller.rb
class CustomersController < ApplicationController
  before_action :authorize_owner
end

複数のアクションに同じ処理が記述されている場合

同じコントローラ内で同じような処理が繰り返し記述されている場合はcallbackを用いて共通化します。
controller

def 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を利用して共通化します。
controller

def 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

  ~省略~

end

set_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.save

after

# 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.rb
class User < ActiveRecord::Base
  def full_name
    "#{family_name} #{first_name}"
  end

def full_name_kana
    "#{family_name_kana} #{first_name_kana}"
  end
end

Decorator(デコレーター)とはビューとモデルの中間に位置し、モデルやビューなどに実装されやすい表示ロジックやフォーマットなどの責務を引き受けるクラスです。
モデルにビューでしか使用しないメソッドが増えていくことがあります。上のfull_nameやfull_name_kanaと言ったメソッドがその例です。こうしたメソッドをデコレーターに移動することでコードの見通しが改善されます。
Railsでデコレーターを使用する場合にはdraperやactive_decoratorと言ったgemを使う方法が一般的です。今回はdraperを使った例を記述します。
active_decorator Github リポジトリ
「デコレーター」を導入するためのgemです。
【例】

app/decorators/user_decorator.rb
class UserDecorator < Draper::Decorator
  delegate_all

  def full_name
    "#{family_name} #{first_name}"
  end

  def full_name_kana
    "#{family_name_kana} #{first_name_kana}"
  end

end
app/controllers/users_controller.rb
class UsersController < ApplicationController
  def show
    @user = User.find(params[:id]).decorate
  end
end
app/views/users/show.html.erb
<%= @user.full_name %>
<%= @user.full_name_kana %>

Validator(バリデーター)

【例】

app/models/article.rb
class Article < ActiveRecord::Base
  validates :url, format: { with: /\A#{URI::regexp(%w(http https))}\z/ }
end
app/models/products.rb
class Article < ActiveRecord::Base
  validates :url, format: { with: /\A#{URI::regexp(%w(http https))}\z/ }
end

モデルの役割の一つにバリデーションがあります。バリデーションとはデータの整合性を保つために、データを検証する機能のことです。
あるモデルのバリデーションに複雑な処理があったり、複数のモデルに共通のバリデーションが存在する場合にはそれらをモデルから切り離すことでリファクタリングが可能になります。
【例】

app/models/articles.rb
class Article < ActiveRecord::Base
  validates :name, url_format: true
end
app/models/products.rb
class Article < ActiveRecord::Base
  validates :url, url_format: true
end
app/validators/url_format_validator.rb
class 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.rb
class event < ActiveRecord::Base
  validates_with RangeValidator
end
app/validators/range_validator.rb
class RangeValidator < ActiveModel::Validator
  def validate(record)
    unless start_time < finish_time
      record.errors.add :base, "finish_timeはstart_timeよりも後に設定してください。"
    end
  end
end

Callback(コールバック)

【例】

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で解読を行っています。このようにコールバック同士に関係性がある場合には別の一つのクラスとして扱うことによって関係性を明確にすることができます。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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

image.png

    .form-group
        = f.label :created_at, class: 'control-label'
        = f.date_select :created_at, class: 'form-control'

time_select

image.png

        = f.label :created_at, class: 'control-label'
        = f.time_select :created_at, class: 'form-control'

datetime_select

image.png

    .form-group
        = f.label :created_at, class: 'control-label'
        = f.datetime_select :created_at, class: 'form-control'

○ xxxx_field

xxxx_fieldは、年、月、日等のテキストフィールドが1つにまとまっており、カレンダー入力ができるようになっています。こっちの方がモダン?

date_field

image.png

    .form-group
        = f.label :created_at, class: 'control-label'
        = f.date_field :created_at, class: 'form-control'

time_field

image.png

    .form-group
        = f.label :created_at, class: 'control-label'
        = f.time_field :created_at, class: 'form-control'

datetime_field

image.png

    .form-group
        = f.label :created_at, class: 'control-label'
        = f.datetime_field :created_at, class: 'form-control'

補足

横並びにしたい場合は、.form-inlineをつけます。.text-leftをつけると左寄りになって、ラベル位置が上下の項目と揃います。

image.png

    .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'
  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

【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に書き換えます。

以上の対応で著者のアプリは久々に起動できました。

おわりに

今回の記事は、読む方をかなり限定するかもしれませんが、それでも誰かのお役に立てれば嬉しいです。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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 変更。

無事、解決しました。

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

(初学者) [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| %>

参考:2.2 Binding a Form to an Object

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

[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: ******

ユーザー詳細ページ

Image from Gyazo

登録編集画面は以下のようになっています。

ユーザー登録編集ページ

Image from Gyazo


パスワードの入力欄がすべてなくなっていますね。
それではユーザー情報を更新してみましょう。
nicknameをテストユーザーに変更し、updateボタンを押します。
すると、、、

変更内容

nickname: sample => テストユーザー

ユーザー詳細ページ(更新後)

Image from Gyazo


名前が sample から テストユーザー に変わりましたね。
以上で終了となります。お疲れ様でした。
また最後までお読みいただきありがとうございました。

補足

補足1)3. edit.html.erbの編集で任意事項(更新後にユーザー詳細ページへ遷移する)を記述した方は、変数@userを使用するため、usersコントローラのshowアクションで以下のように定義しておく必要があります。

controllers/users_controller.rb
  def 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 %>

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む

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

  • このエントリーをはてなブックマークに追加
  • Qiitaで続きを読む