- 投稿日:2020-09-13T23:46:19+09:00
rails generate controllerした時に不要なファイルを出さない設定(RSpec編)
Ruby on Railsで新しくコントローラーを作る時に、不要なファイルを出さない様に設定をいれるか、オプションを指定する方法です。
システム環境
環境に依存する話ではないと思いますが、私の環境は以下の通りです。
- Ruby 2.6.3
- Rails 6.0.3.3
- RSpec 3.9
Before:設定がない時
デフォルトの状態で
rails g controller hoges
すると、以下の様なファイルが生成されます。昔はcontroller specも生成された気がしますが、controller specは公式が推奨していないので、今は出ないみたいです。$ rails g controller Hoges new create app/controllers/samples_controller.rb route get 'samples/new' invoke erb create app/views/samples create app/views/samples/new.html.erb invoke rspec create spec/requests/samples_request_spec.rb create spec/views/samples create spec/views/samples/new.html.erb_spec.rb invoke helper create app/helpers/samples_helper.rb invoke rspec create spec/helpers/samples_helper_spec.rb invoke assets invoke scss create app/assets/stylesheets/samples.scssでも、「controllerごとにcssを分けないよね」とか「Helperも使わないよね」ということもあるんじゃないでしょうか(←私)。
生成したファイルを手動で毎回消していましたのですが、面倒なので設定してしまうことにしました。設定の方法
RSpecをテストフレームワークに設定している方はすでにconfig/application.rbに
config.generators do
の記載があると思いますので、その前後に以下の様に記述を足します。config/application.rbconfig.generators do |g| g.skip_routes true #routesの自動記述をoff g.helper false #app/helperの自動生成をoff g.assets false #同名のcssやjsの生成をoff g.test_framework :rspec, #標準のテストをRSpecに変更 controller_specs: false, #公式で非推奨のためoff view_specs: false, #Request/Systemで代替するのでoff routing_specs: false #使用頻度低いのでoff endskip_routesは結局
resouces :hoge, only: :new
の様にresourcesで書き換えてしまうことが多いので、デフォルトではオフにしています。
app/hoge_helper.rbも意外と使わないのでオフ。assetsも使用頻度が少ないのでオフ。このあたりの不要なファイルは、後から他の人が見た時のことを考えて記載しない場合は消しておいた方が良いらしいです(確認の手間も増えますしね)。After:設定がある時
設定を入れてrails g controller hoges newを実行すると、結果は以下の通りです。
$rails g controller Samples new create app/controllers/samples_controller.rb invoke erb create app/views/samples create app/views/samples/new.html.erb invoke rspec create spec/requests/samples_request_spec.rbこれである程度スッキリしたのではないでしょうか。
ご参考:コマンドのオプションで指定する方法
config/application.rbに記載して設定するのではなく、都度オプションで指定する方法もあります。
$rails g controller samples new --no-assets
Option 省略されるもの --no-assets app/assets/以下の.js, .cssファイル --no-helper app/helpers以下のHelperファイル --no-test-framework Specファイル。上の場合だとrequest specが省略されます --skip-routes --skip-template-engine
- 投稿日:2020-09-13T23:07:39+09:00
herokuでのデプロイの仕方
【概要】
1.手順
2.方法
1.手順
❶brew tap heroku/brew && brew install heroku
❷gem 'rails_12factor'
❸heroku用ファイルの作成
❹heroku用DBの作成
❺環境変数の設定
❻heroku上でmasterにpush
❼heroku上でマイグレーションの実施
2.方法
❶brew tap heroku/brew && brew install heroku
ターミナル% brew tap heroku/brew && brew install heroku
を実行しましょう!ミスしないようにherokuに公開したいアプリの該当ファイルで行うことをお勧めします!
そして% heroku login --interactive
でherokuにログインしておきます!❷gem 'rails_12factor'
gemfilegroup :production do gem 'rails_12factor' endと記載し、% bundle installをします!
そしてmasterにコミットしておきます。❸heroku用ファイルの作成
ターミナル% heroku create *****でherokuに公開したいアプリの名前を作成します。
❹heroku用DBの作成
ターミナル% heroku addons:add cleardb
と記載しデーターベースを作成します。
ターミナル% heroku config | grep CLEARDB_DATABASE_URL
これにより、CLEARDB_DATABASE_URLが出てくるので、使用状況によりmysql2を使用している方は、変更しましょう。
>変更方法<
ターミナル% heroku config:set DATABASE_URL = 'mysql2:*****'****の部分は% heroku config | grep CLEARDB_DATABASE_URLでてきたものをコピペします。
❺環境変数の設定
ターミナル% heroku config:set RAILS_MASTER_KEY=`cat config/master.key`
こうすることで、パスワードをファイルの中に書き込まず、見られないようにしてサイトを見るようにできます。
❻heroku上でmasterにpush
ターミナル% git push heroku master
こちらでherokuにpushできます。
❼heroku上でマイグレーションの実施
ターミナル% heroku run rails db:migrate
DBを❹で作っているのでそれをローカルと同じようにherokuでもマイグレーションしていきます。
これでherokuにアプリを公開できるようになります。
ただパスワードを設定していないので誰でもそのサイトを覗ける状態になっているので注意してください。
環境変数はあくまでも自分のサイトを乗っ取られないようにするためものです。
- 投稿日:2020-09-13T22:59:46+09:00
【Rails,heroku】多量csvを分割splitしてDBにseedして流し込む
参考記事
http://yu0105teshi.hateblo.jp/entry/2016/08/03/180603
https://qiita.com/masaki7555/items/d65f56958020cbca5ee0この記事の内容を使っているサイト:薬価計算medipra
この記事で紹介すること
行数が多いCSVファイルをコマンドで分割する方法
CSVファイルを使ってDBにデータを入れる行数が多いCSVファイルをコマンドで分割する方法
ではまずCSVの準備をします。
CSVファイルの準備
必要なCSVファイルを用意します。
今回は医薬品データベースを使用します。ここから、「全件分ファイル」をダウンロードすると、約21,000行あるCSVファイルが手に入ります。
ターミナルを開いてCSVファイルをダウンロードしたディレクトリに移動しましょう。
そこでwc -l [ファイル名]
を実行すると、指定したファイルの行数がカウントされます。
ちなみにwcコマンドの主なオプションは以下の通りです。
短いオプション 長いオプション 意味 -c --bytes バイト数の表示 -m --chars 文字数の表示 -l --lines 改行の数を表示 -w --words 単語数を表示 CSVファイルの分割split
それでは次にダウンロードしたCSVファイルを分割します。
そもそもなぜ分割するのかというと、
今回の場合は、使ってるherokuのAdd-onの設定によります。今、薬価計算サイトmedipraで使用しているclearDB MySQLの有料プランがPunch($9.99)で、
1時間当たり18,000のクエリしか受け付けないためです。
なので、ダウンロードしたファイルをそのままDBに流し込もうとすると、クエリが足りなくなりエラーとなってしまいます。
たまに更新するDBのためにより上の有料プランを契約するのも、ランニングコストが増えるので初めの段階では不要ですよね。また、CSVを1行流し込むのにクエリが3回飛ぶようなので、6,000行以下でファイルを分割します(今回は余裕を持って5,900行で分割してます)
さて、分割してみましょう。
分割コマンドは
$ split -l [行数] [分割するファイル] [分割したファイルの接頭辞]
で、行数を指定して分割できます。赤い下線の
--additional -suffix=.csv
のところは、分割後のファイルの拡張子をCSVにしたくて付け足したのですが、デフォルトでマックに入っているのではこのオプションは使えないようです。というわけで次のコマンドで分割。
$ split -l 5900 y_ALL20200825.csv medipra-このコマンドで
medipra-aa, medipra-ab, medipra-ac, medipra-adの4つのファイルができました。今回はcsvファイルにしたいので、名前の変更で
.csv
にすればCSVファイルとして使えるようになります。分割後のCSVファイルが文字化けしていたら
分割後にVSCodeで開いてみると文字化けしていることがあります。
そんな時はExcelで開いて「名前をつけて保存」をクリックして、
ファイル形式をCSV UTF-8と文字コードを指定して保存してみましょう。CSVファイルを使ってDBにデータを入れる
大まかな解説
ファイル構造は以下のようになります。
(seeds.rbは不要ファイルなので気にしないでください)dbディレクトリの直下にCSVファイルをおき、これらをseeds>product1.rbでDBに流し込みます。
先に、今回使うコマンドはこちら。(herokuの環境を想定しています)
$ heroku login $ heroku run bundle exec rake db:migrate:reset $ heroku run bundle exec rake db:seed:product1
db:migrate:reset
についてはこちらを参照してください。
参考記事:rake db:reset と rake db:migrate:reset の違いseeds>product1.rbの準備
今回は、多量のCSVのデータを複数に分けて流すのでseedファイルを必要な分作ります。
今回なら、CSVファイルが4つありますので4つのseedが必要になります。seedsディレクトリを作って、そのしたのディレクトリにファイルを作ります。
例えば以下のようにファイルを作ります。
product1.rbrequire "csv" date = "2020-04-01" i = 1 CSV.foreach('db/medipra20200825-a.csv') do |info| Product.create!( price: info[11], change_category: info[0], master_type: info[1], pharmaceutical_code: info[2], ・・・中略・・・ expiration_date: info[33], standard_name: info[34] ) end
db/medipra20200825-a.csv
の部分をそれぞれファイル名を変えてproduct1.rb~product4.rbまで作ります。こちらも参考にどうぞ
【Rails】rake seedコマンドでCSVファイルからDBに読み込ませる方法seedコマンドでDBに流し込む
seedファイルを用意したら、コマンドで流し込みます。
まずherokuにログイン
$ heroku login続いて、前の古いDBがあるならresetします
$ heroku run bundle exec rake db:migrate:resetこれで最新のマイグレーションファイルのDBが作り直すことができます。
最後にseedを実行。
product1~4まであるので、4回実行することになります。$ heroku run bundle exec rake db:seed:product1クエリが1時間当たり18,000までなので、
1回このコマンドをやったら、1時間開けて~:product2
に変更して、
再度コマンドを実行します。若干手間ではありますが、これ以上課金するのもまだもったいないので。(費用対効果、大事ね)
以上で完成です。
間違いのご指摘などありましたらご教示いただけましたら幸いですm(__)m
それでは今回は以上です。
最後までありがとうございます。この記事の内容を使っているサイト:薬価計算medipra
- 投稿日:2020-09-13T22:59:46+09:00
【Rails,heroku】多量csvをsplitしてseedして流し込む
参考記事
http://yu0105teshi.hateblo.jp/entry/2016/08/03/180603
https://qiita.com/masaki7555/items/d65f56958020cbca5ee0この記事の内容を使っているサイト:薬価計算medipra
この記事で紹介すること
行数が多いCSVファイルをコマンドで分割する方法
CSVファイルを使ってDBにデータを入れる行数が多いCSVファイルをコマンドで分割する方法
ではまずCSVの準備をします。
CSVファイルの準備
必要なCSVファイルを用意します。
今回は医薬品データベースを使用します。ここから、「全件分ファイル」をダウンロードすると、約21,000行あるCSVファイルが手に入ります。
ターミナルを開いてCSVファイルをダウンロードしたディレクトリに移動しましょう。
そこでwc -l [ファイル名]
を実行すると、指定したファイルの行数がカウントされます。
ちなみにwcコマンドの主なオプションは以下の通りです。
短いオプション 長いオプション 意味 -c --bytes バイト数の表示 -m --chars 文字数の表示 -l --lines 改行の数を表示 -w --words 単語数を表示 CSVファイルの分割split
それでは次にダウンロードしたCSVファイルを分割します。
そもそもなぜ分割するのかというと、
今回の場合は、使ってるherokuのAdd-onの設定によります。今、薬価計算サイトmedipraで使用しているclearDB MySQLの有料プランがPunch($9.99)で、
1時間当たり18,000のクエリしか受け付けないためです。
なので、ダウンロードしたファイルをそのままDBに流し込もうとすると、クエリが足りなくなりエラーとなってしまいます。
たまに更新するDBのためにより上の有料プランを契約するのも、ランニングコストが増えるので初めの段階では不要ですよね。また、CSVを1行流し込むのにクエリが3回飛ぶようなので、6,000行以下でファイルを分割します(今回は余裕を持って5,900行で分割してます)
さて、分割してみましょう。
分割コマンドは
$ split -l [行数] [分割するファイル] [分割したファイルの接頭辞]
で、行数を指定して分割できます。赤い下線の
--additional -suffix=.csv
のところは、分割後のファイルの拡張子をCSVにしたくて付け足したのですが、デフォルトでマックに入っているのではこのオプションは使えないようです。というわけで次のコマンドで分割。
$ split -l 5900 y_ALL20200825.csv medipra-このコマンドで
medipra-aa, medipra-ab, medipra-ac, medipra-adの4つのファイルができました。今回はcsvファイルにしたいので、名前の変更で
.csv
にすればCSVファイルとして使えるようになります。分割後のCSVファイルが文字化けしていたら
分割後にVSCodeで開いてみると文字化けしていることがあります。
そんな時はExcelで開いて「名前をつけて保存」をクリックして、
ファイル形式をCSV UTF-8と文字コードを指定して保存してみましょう。CSVファイルを使ってDBにデータを入れる
大まかな解説
ファイル構造は以下のようになります。
(seeds.rbは不要ファイルなので気にしないでください)dbディレクトリの直下にCSVファイルをおき、これらをseeds>product1.rbでDBに流し込みます。
先に、今回使うコマンドはこちら。(herokuの環境を想定しています)
$ heroku login $ heroku run bundle exec rake db:migrate:reset $ heroku run bundle exec rake db:seed:product1
db:migrate:reset
についてはこちらを参照してください。
参考記事:rake db:reset と rake db:migrate:reset の違いseeds>product1.rbの準備
今回は、多量のCSVのデータを複数に分けて流すのでseedファイルを必要な分作ります。
今回なら、CSVファイルが4つありますので4つのseedが必要になります。seedsディレクトリを作って、そのしたのディレクトリにファイルを作ります。
例えば以下のようにファイルを作ります。
product1.rbrequire "csv" date = "2020-04-01" i = 1 CSV.foreach('db/medipra20200825-a.csv') do |info| Product.create!( price: info[11], change_category: info[0], master_type: info[1], pharmaceutical_code: info[2], kanji_significant_digits: info[3], kanji_name: info[4], kana_significant_digits: info[5], kana_name: info[6], unit_code: info[7], unit_significant_digits: info[8], unit_name: info[9], price_type: info[10], spare: info[12], n_p_s_p_drugs: info[13], nerve_destroyer: info[14], biologics: info[15], generic: info[16], spare_2: info[17], dental_drugs: info[18], contrast_agent: info[19], injection_volume: info[20], listing_type: info[21], product_name_relations: info[22], old_price_type: info[23], old_price: info[24], name_change_category: info[25], kana_name_change_category: info[26], dosage_form: info[27], spare_3: info[28], changed_date: info[29], abolition_date: info[30], standard_code: info[31], order_number: info[32], expiration_date: info[33], standard_name: info[34] ) end
db/medipra20200825-a.csv
の部分をそれぞれファイル名を変えてproduct1.rb~product4.rbまで作ります。こちらも参考にどうぞ
【Rails】rake seedコマンドでCSVファイルからDBに読み込ませる方法seedコマンドでDBに流し込む
seedファイルを用意したら、コマンドで流し込みます。
まずherokuにログイン
$ heroku login続いて、前の古いDBがあるならresetします
$ heroku run bundle exec rake db:migrate:resetこれで最新のマイグレーションファイルのDBが作り直すことができます。
最後にseedを実行。
product1~4まであるので、4回実行することになります。$ heroku run bundle exec rake db:seed:product1以上で完成です。
間違いのご指摘などありましたらご教示いただけましたら幸いですm(__)m
この記事の内容を使っているサイト:薬価計算medipra
- 投稿日:2020-09-13T22:26:34+09:00
【Rails】データを削除する様々な方法
早見表
メソッド 説明 削除する範囲 destroy 一件のデータを削除 対象データと関連データを削除 destroy_all 複数データを削除 対象データと関連データを削除 delete 一件のデータを削除 対象データのみ削除 delete_all 複数データを削除 対象データのみ削除
関連するデータ
dependent: :destroy
で依存関係にあるデータのこと使い方
# destroyメソッド User.find(1).destroy # destroy_allメソッド User.where(id: 1..5).destroy_all # deleteメソッド User.find(1).delete # delete_allメソッド User.where(id: 1..5).delete_all
- 投稿日:2020-09-13T20:22:29+09:00
[heroku] run rails db:migrateがうまくいかない
環境
・Rails 6.0.3.2
・mysql Ver 14.14 Distrib 5.6.47
・osx10.15
・herokuへデプロイはじめに
Rails
でアプリを作成しheroku
へアップロードするときにうまくいかなかった時の対応です。
開発環境ではMySQL
でheroku
ではDBがPostgreSQL
のためその対応が必要。
その途中段階でエラーが生じた。
順番に書いていきます。PostgreSQLへの対応
まずは
Gemfile
へ以下を記述。本番環境でPostgreSQL
を使うというものです。自分は一番下に書きました。group :production do gem 'pg' endGemfileを変更したので忘れずにbundle installをします。
まずここで一つ目のエラーでました。そのままbundle install
すると自分の開発環境にはPostgreSQL
がないのでエラー発生。対応は
group :produciton end
のところを飛ばすコマンドをターミナルで実行します。$ bundle install --without productionデータベースへ接続する記述をconfigフォルダの中にある
database.yml
へします。
一番下へ追記しました。production: <<: *default adapter: postgresql encoding: unicode pool: 5自分の場合は記述は以上でした。
参考になった記事はコチラです!
【初心者向け】railsアプリをherokuを使って確実にデプロイする方法【決定版】
・https://qiita.com/kazukimatsumoto/items/a0daa7281a3948701c39herokuへデプロイ
今回ここは割愛します。
デプロイ完了まで進みます。ここでdb:migrate
heroku run rails db:migrate
をしますがエラー発生!
いろいろ見ているうちにこのエラーにやっと出会う。。。ターミナルには中ほどに以下のような記述が。
Caused by: PG::ConnectionBad: could not connect to server: No such file or directory Is the server running locally and accepting connections on Unix domain socket "/var/run/postgresql/.s.PGSQL.5432"?原因
調べてみると単純なことで
heroku
にはデフォルトではPostgreSQL
が入ってないので、追加してあげる必要があるということです!
なんと!!!!
まだまだ慣れてないのでこの単純なことに気づけませんでした。。。。対応
ターミナルで
PostgreSQL
を追加するコマンド$ heroku addons:create heroku-postgresqlその後に
$ heroku run rails db:migrateそうするとマイグレーションが完了しました!
別のところが誤っていると思い全然違うことをして数時間を費やしてしまいましたが、単純なことでした!
無事アプリが動作し完了しました!参照
【初心者向け】railsアプリをherokuを使って確実にデプロイする方法【決定版】
・https://qiita.com/kazukimatsumoto/items/a0daa7281a3948701c39【Rails】「heroku run rake db:migrate」を実行しようとすると発生するエラーについて
・https://qiita.com/suzuki-x/items/b878723080aea1a673ed
- 投稿日:2020-09-13T19:37:13+09:00
【Rails】ビューに画像を表示する方法
初投稿です。
至らぬ点もあるかと思いますので暖かい目で見守っていただけると幸いです・・・Railsで画像を表示する方法にかなり手こずったのでメモとしての記録です。
それでは早速参りましょう!※haml・scssで記述しています。
画像を表示する方法
まずは、スタンダードに画像を表示する方法。
haml・scssどちらに書いても表示されるみたいです。
どっちに書くのが正解なのと思うところです。個人的な印象としては画像を背景として使いたい時、
例えば画像の上にテキスト情報表示したい時とか。
そんなときは、background-imageとしてscssに記述したほうが良さげ。
ここの違いよくわからないので違いがわかる方いたらご教授いただきたいですまず、表示する画像がないといけません。
app/assets/images
こちらのディレクトリーに表示したい画像を格納して準備完了です。hamlに記述する場合
ファイル名.html.haml= image_tag ("画像名.jpg")これじゃまだ表示できないんですよね。
widthとheightを設定してあげないと表示されません。
そんな時は、scssに画像を整える記述を書く必要があります。_ファイル名.scssimg { width: 100%; height: 100%; }こんな感じで、width: 100%;とheight: 100%;を指定すると無事表示されます。
今回の場合は「%」ですが「px」でも可能!
hamlで書く時は”= image_tag”これが必須ですね。scssに記述する場合
_ファイル名.scss.クラス名 { height: 560px; width: 100%; background-image: image-url("ファイル名.jpg"); background-size: cover; background-repeat: no-repeat; background-position: top center; }こんな感じで書くと表示できます。
background-sizeとかその辺のプロパティ書かないと、
画像が「ばぁぁぁぁあぁぁん」ってなります。(悲惨)
あとは、widthとheightの設定も必要です。
実装したいイメージにあったプロパティを選択する必要があります。本番環境でのみ画像が表示されない
ローカル環境で表示されるのに、本番環境で表示されない・・・
なんてこともあります。表示できないときのコードがこちら
_ファイル名.scss.クラス名 { height: 560px; width: 100%; background-image: url("ファイル名.jpg"); background-size: cover; background-repeat: no-repeat; background-position: top center; }上のコードと見比べて違うところは
_ファイル名.scss.クラス名 { background-image: url("ファイル名.jpg"); }この部分です。
この書き方だと、ローカルでは表示できるけど、本番では表示されません。_ファイル名.scss.クラス名 { background-image: image-url("ファイル名.jpg"); }このように修正することでで本番でもローカルでも表示できるようになります。
データベースにある画像を表示する方法
例えば、商品を登録するときに画像も登録することがあります。
登録した画像を表示したい!!そんな時の方法です。◇条件1◇画像は別テーブルで保存する場合
別テーブルで保存する理由は、複数枚画像を登録するためです。
一枚だけ登録する場合は、テーブルを分ける必要はないかと思います。コントローラー名.rbdef index @items = Item.includes(:item_images).order("created_at DESC").limit(5) endこんな感じで情報を取得。
item_imagesは画像を保存している箇所です。ファイル名.html.haml- @items.each do |item| #eachで展開 = image_tag item.item_images[0].image.url_ファイル名.scssimg { width: 100%; height: 100%; }このように書くと表示できました。
正直、めっちゃ記述長い・・・そんな印象
[0]→画像は配列で格納されているみたいで何枚目かの指定をする必要があります。◇条件2◇画像は別テーブルで保存しない場合
html.erbの記載となります。
コントローラー名.rbdef index @items = Item.order("created_at DESC").page(params[:page]).per(5) endこんな感じで情報を取得。
ファイル名.html.erb<% @items.each do |item| %> <%= image_tag item.image.to_s, :size =>'220x220'%>ちゃっかり、ファイル名.html.erb内でサイズ指定しちゃっています。
これで表示できました他に、表示する方法あればご教授いただきたいです
- 投稿日:2020-09-13T19:04:05+09:00
(ギリ)20代の地方公務員がRailsチュートリアルに取り組みます【第8章】
前提
・Railsチュートリアルは第4版
・今回の学習は3周目(9章以降は2周目)
・著者はProgate一通りやったぐらいの初学者基本方針
・読んだら分かることは端折る。
・意味がわからない用語は調べてまとめる(記事最下段・用語集)。
・理解できない内容を掘り下げる。
・演習はすべて取り組む。
・コードコピペは極力しない。
第8章はログインと認証システムの開発・第3段回目、基本的なログイン機構を実装していきます。(第9章でさらに発展させていきます)
情報技術の用語が飛び交いますので、それぞれの用語の意味・動作も理解しながら進めていきましょう。
本日のBGMは趣向を変えて。
TVアニメ「ゆるキャン△」オリジナル・サウンドトラック
やっと涼しくなってきました。キャンプに最適なシーズンです。コーディングで疲れた眼と頭のリフレッシュに行きましょう。
【8.1.1 Sessionsコントローラ 演習】
1. GET login_pathとPOST login_pathとの違いを説明できますか? 少し考えてみましょう。
→ GETはログインページのビュー取得(newアクション)、POSTはフォームに入力したデータを送信してログインを実行(createアクション)。
2. ターミナルのパイプ機能を使ってrails routesの実行結果とgrepコマンドを繋ぐことで、Usersリソースに関するルーティングだけを表示させることができます。同様にして、Sessionsリソースに関する結果だけを表示させてみましょう。現在、いくつのSessionsリソースがあるでしょうか? ヒント: パイプやgrepの使い方が分からない場合は Learn Enough Command Line to Be Dangerousの Section on Grep (英語) を参考にしてみてください。
→ パイプ機能:(コマンド) | (コマンド) のようにコマンド同士を繋ぐ機能。
grepコマンド:ファイル中の文字列を検索するコマンド。
ということで下記。signupが入ってしまうのは仕方ない?$ rails routes | grep users# signup GET /signup(.:format) users#new POST /signup(.:format) users#create users GET /users(.:format) users#index POST /users(.:format) users#create new_user GET /users/new(.:format) users#new edit_user GET /users/:id/edit(.:format) users#edit user GET /users/:id(.:format) users#show PATCH /users/:id(.:format) users#update PUT /users/:id(.:format) users#update DELETE /users/:id(.:format) users#destroy$ rails routes | grep sessions# login GET /login(.:format) sessions#new POST /login(.:format) sessions#create logout DELETE /logout(.:format) sessions#destroy
【8.1.2 ログインフォーム 演習】
1. リスト 8.4で定義したフォームで送信すると、Sessionsコントローラのcreateアクションに到達します。Railsはこれをどうやって実現しているでしょうか? 考えてみてください。ヒント:表 8.1とリスト 8.5の1行目に注目してください。
→ routesファイルのpost '/login', to: 'sessions#create'の一文でしょう。form_forでpostリクエストを発行→ルーティングでsessionsコントローラのcreateアクションに割り当て。
【8.1.3 ユーザーの検索と認証 演習】
1. Railsコンソールを使って、表 8.2のそれぞれの式が合っているか確かめてみましょう. まずはuser = nilの場合を、次にuser = User.firstとした場合を確かめてみてください。ヒント: 必ず論理値オブジェクトとなるように、4.2.3で紹介した!!のテクニックを使ってみましょう。例: !!(user && user.authenticate('foobar'))
→ 下記>> user = nil => nil >> !!(user && user.authenticate("foobar")) => false >> user = User.first User Load (0.1ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ? [["LIMIT", 1]] => #<User id: 1, name: "Rails Tutorial", email: "example@railstutorial.org", created_at: "2020-09-12 09:09:50", updated_at: "2020-09-12 09:09:50", password_digest: "$2a$10$hrOEzw0faSd4yurmH8bQJOnggeNnUqTZg33yE9g7Tnk..."> >> !!(user && user.authenticate("matigatteruyo")) => false >> !!(user && user.authenticate("hogehoge")) => true
【8.1.5 フラッシュのテスト 演習】
1. 8.1.4の処理の流れが正しく動いているかどうか、ブラウザで確認してみてください。特に、flashがうまく機能しているかどうか、フラッシュメッセージの表示後に違うページに移動することを忘れないでください。
→ 試してみましょう。違うページに行くとフラッシュが消えます。
【8.2.1 log_in メソッド 演習】
1. 有効なユーザーで実際にログインし、ブラウザからcookiesの情報を調べてみてください。このとき、sessionの値はどうなっているでしょうか? ヒント: ブラウザでcookiesを調べる方法が分からない? 今こそググってみるときです! (コラム 1.1)
2. 先ほどの演習課題と同様に、Expiresの値について調べてみてください。
→ まとめて下の画像。Expires = 期限切れなので、緑の四角内です。ブラウザセッション終了時が有効期限になっていますね。
【8.2.2 現在のユーザー 演習】
1. Railsコンソールを使って、User.find_by(id: ...)で対応するユーザーが検索に引っかからなかったとき、nilを返すことを確認してみましょう。
→ 下記>> User.find_by(id: 8) User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 8], ["LIMIT", 1]] => nil
2. 先ほどと同様に、今度は:user_idキーを持つsessionハッシュを作成してみましょう。リスト 8.17に記したステップに従って、||=演算子がうまく動くことも確認してみましょう。
→ 下記>> session = {} => {} >> session[:user_id] = nil => nil >> @current_user ||= User.find_by(id: session[:user_id]) User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" IS NULL LIMIT ? [["LIMIT", 1]] => nil >> session[:user_id] = User.first.id User Load (0.1ms) SELECT "users".* FROM "users" ORDER BY "users"."id" ASC LIMIT ? [["LIMIT", 1]] => 1 >> @current_user ||= User.find_by(id: session[:user_id]) User Load (0.1ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? LIMIT ? [["id", 1], ["LIMIT", 1]] => #<User id: 1, name: "Rails Tutorial", email: "example@railstutorial.org", created_at: "2020-09-12 09:09:50", updated_at: "2020-09-12 09:09:50", password_digest: "$2a$10$hrOEzw0faSd4yurmH8bQJOnggeNnUqTZg33yE9g7Tnk..."> >> @current_user ||= User.find_by(id: session[:user_id]) => #<User id: 1, name: "Rails Tutorial", email: "example@railstutorial.org", created_at: "2020-09-12 09:09:50", updated_at: "2020-09-12 09:09:50", password_digest: "$2a$10$hrOEzw0faSd4yurmH8bQJOnggeNnUqTZg33yE9g7Tnk...">
【8.2.3 レイアウトリンクを変更する 演習】
1. ブラウザのcookieインスペクタ機能を使って (8.2.1.1)、セッション用のcookieを削除してみてください。ヘッダー部分にあるリンクは非ログイン状態のものになっているでしょうか? 確認してみましょう。
→ やってみるだけ。非ログイン状態になりました。
2. もう一度ログインしてみて、ヘッダーのレイアウトが変わったことを確認してみましょう。その後、ブラウザを再起動させ、再び非ログイン状態に戻ったことも確認してみてください。注意: もしブラウザの [閉じたときの状態に戻す] 機能をオンにしていると、セッション情報も復元される可能性があります。もしその機能をオンにしている場合、忘れずにオフにしておきましょう (コラム 1.1)。
→ やってみるだけー。
【8.2.4 レイアウトの変更をテストする メモと演習】
ここのdigestメソッドのコードの書き方は正直??状態。:を2つ書くのってどういう意味なんでしょうか。前からちょくちょく出てきてるけど。調べると、PHPの記法は出てくるけど、同じような意味にとっていいのだろうか。
テストのアサーションなんかは用語集にまとめてます。1. 試しにSessionヘルパーのlogged_in?メソッドから!を削除してみて、リスト 8.23が redになることを確認してみましょう。
2. 先ほど削除した部分 (!) を元に戻して、テストが greenに戻ることを確認してみましょう。
→ まとめて。当然失敗します。ヘッダーの表示がログイン・非ログイン時で逆になっちゃうから。戻せばGREENです。
【8.2.5 ユーザー登録時にログイン メモと演習】
この章ではいろんなヘルパーメソッドを定義していますね。どこで使うために、どこに定義しているの意識しながらコードを書きましょう。コントローラで使うのか、テストで使うのか等。
1. リスト 8.25のlog_inの行をコメントアウトすると、テストスイートは red になるでしょうか? それとも green になるでしょうか? 確認してみましょう。
→ REDになります。テストにログイン状態か確かめるコード書いているので。
2. 現在使っているテキストエディタの機能を使って、リスト 8.25をまとめてコメントアウトできないか調べてみましょう。また、コメントアウトの前後でテストスイートを実行し、コメントアウトすると red に、コメントアウトを元に戻すと green になることを確認してみましょう。ヒント: コメントアウト後にファイルを保存することを忘れないようにしましょう。また、テキストエディタのコメントアウト機能については Test Editor Tutorial の Commenting Out (英語) などを参照してみてください。
→ (Macの場合)command+Aで全選択、command+/でコメントアウト。当然コメントアウトの前後でRED/GREENになります。
【8.3 ログアウト メモと演習】
1. ブラウザから [Log out] リンクをクリックし、どんな変化が起こるか確認してみましょう。また、リスト 8.31で定義した3つのステップを実行してみて、うまく動いているかどうか確認してみましょう。
→ ちゃんと動きます。
2. cookiesの内容を調べてみて、ログアウト後にはsessionが正常に削除されていることを確認してみましょう。
→ 削除されてます。
第7章まとめ
・sessionメソッドで一時的な状態保存。
・ログインではActive RecordのUserモデルを使わないので、関連づけられたエラーメッセージは使えない。
・flash.nowでrenderしたページのみフラッシュメッセージを表示。
・form_forはform_withに置き換わってるようなので参考までに。
・renderとredirect_toの使い分け。
・flashメッセージを表示。
・統合テストでログインまわりの実装を一通りテスト(ログイン/ログアウトできているか、ヘッダーは切り替わっているか)
この章は大きなエラーなく進められました。次の9章から発展的な機構を導入していきます。遂に1周しかしていない章に入っていきますね!気合入れていきましょう!
⇦ 第7章はこちら
学習にあたっての前提・著者ステータスはこちら
なんとなくイメージを掴む用語集
・ステートレス・プロトコル
状態の保持をしない独立した情報のやりとり。ログイン機能に例えると、一回ブラウザを閉じて再度入り直すと、ログインし直しになる。・セッション(session)
一連の通信のこと(ログインからログアウトまで等)。ェブサイトでは、初めて訪問した場合にブラウザのcookieに書き込まれる識別子のこと。・cookie
HTTPにおけるウェブサーバとウェブブラウザ間で状態を管理する通信プロトコル、またそこで用いられるウェブブラウザに保存された情報のこと。ECサイトの買い物カゴやログイン機能等で使われている。溜まってきたなと思ってブラウザの設定とかから消せるアレ。・assert_redirected_to
このアサーションの直前で呼び出されたリダイレクト先と、to以下のリダイレクト先が一致するかどうかテストする。・follow_redirect!
実際にそのページに移動する。移動した先で他の要素をテストする際に利用。
- 投稿日:2020-09-13T18:00:41+09:00
Rails チュートリアル バージョン違いで rails new できない時
超超初心者向けです。
railsチュートリアルで新しいアプリの作成時に
$ rails 6.0.3 new hello_app
を実行すると、
Traceback (most recent call last):
.
.
can't find gem railties (= 6.0.3) with executable rails (Gem::GemNotFoundException)このようなエラーが出てしまいました。
https://teratail.com/questions/80979
↑こちらの記事を参考にさせていただいて
$ gem install rails -v 6.0.3
でgem をインストールしてもう一度
$ rails 6.0.3 new hello_app
することで解決しました。
- 投稿日:2020-09-13T17:25:58+09:00
アウトプット2 ~ユーザ登録機能~
ユーザ登録機能を作ります。
users/newもしくは、自らルーティングした/signupで。
userscontrollerのアクションですが、userscontroller.rbdef new @user = User.new def create @user = User.new(user_params) if @user.save flash[:success] = "ユーザを登録しました。" redirect_to root_path else flash.now[:danger] ="ユーザの登録に失敗しました" render :new private def user_params params.require(:user).permit(:name,:email,:password,:password_confirmation) endとしました。
privateはこのクラスのみで使えるプライヴェーとメソッド。
user_paramsはストロングパラメータです。
送信されてきたデータに対して、フィルターをかけようというものです。
今回、送られてきたuserモデルからのパラメータに対し、permitで指定したデータ以外は許可しないようにしています。
@user = User.new(user_params)で、paramsはuserモデルのname~password_confirmationのカラムしか受け取らないようにします。コントローラー設定が終わったので、viewsです。
new.htl.erb<div class="text-center"> <h1>ユーザー登録</h1> </div> <div class="row"> <div class="col-sm-6 offset-sm-3"> <%= form_with(model: @user, local: true) do |f| %> <%= render "layouts/error_messages", model: f.object %> <!--create失敗時フラッシュメッセージ--> <div class="form-group"> <%= f.label :name, "Name" %> <%= f.text_field :name, class: "form-control" %> </div> <div class="form-group"> <%= f.label :email, "Email" %> <%= f.email_field :email, class: "form-control" %> </div> <div class="form-group"> <%= f.label :password, "Password" %> <%= f.password_field :password, class: "form-control" %> </div> <div class="form-group"> <%= f.label :password_confirmation, "Password-Confirmation" %> <%= f.password_field :password_confirmation, class: 'form-control' %> </div> <%= f.submit "新規登録", class: "btn btn-primary btn-block" %> <% end %> </div> </div>フォームを設置しました。
form-with(model: モデル名)ですが、モデルがない場合はurlを指定します。
- 投稿日:2020-09-13T15:42:05+09:00
Heroku便利なコマンド大全!!
Herokuへの初回push
$ cd <レポジトリ名> $ git init $ heroku create <アプリ名> $ heroku git:remote -a <アプリ名> # addした名前を確認出来ます $ git remote -v $ git add . $ git commit -c "comment" $ git push <アプリ名> masterHeroku app一覧の表示
heroku appsHeroku環境にあるアプリの概要表示
これはかなり使えます!!アプリのURLとかも表示してくれるので!
Ruby on Railsのチュートリアルで、「本番環境で〇〇を確認してください」
とよくあると思いますが、このコマンド打てば本番環境のURLを一発で確認できます!heroku info --app <アプリ名>Heroku logの確認
heroku logsデータベースのパス取得
$ heroku config --app <アプリ名> CLEARDB_DATABASE_URL:mysql://ユーザ名:パスワード@サーバ名(ホスト名)/データベース?reconnect =true
- 投稿日:2020-09-13T14:11:38+09:00
Rails:Deviseを使用するまでの手順
動機
railsでユーザー認証機能の作成を行ったが難しかったため
メモとして残しておくdeviseのインストール
$ rails g devise:installまずはdeviseのインストールを行う
インストールが完了すると以下が表示される
Depending on your application's configuration some manual setup may be required: 1. Ensure you have defined default url options in your environments files. Here is an example of default_url_options appropriate for a development environment in config/environments/development.rb: config.action_mailer.default_url_options = { host: 'localhost', port: 3000 } In production, :host should be set to the actual host of your application. * Required for all applications. * 2. Ensure you have defined root_url to *something* in your config/routes.rb. For example: root to: "home#index" * Not required for API-only Applications * 3. Ensure you have flash messages in app/views/layouts/application.html.erb. For example: <p class="notice"><%= notice %></p> <p class="alert"><%= alert %></p> * Not required for API-only Applications * 4. You can copy Devise views (for customization) to your app by running: rails g devise:views * Not required *1.mailerの設定
1ではmailerの設定をしてと言っているので'config/environments/development.rb:'のmailer設定のところに以下のように記述
# Don't care if the mailer can't send. config.action_mailer.raise_delivery_errors = false config.action_mailer.perform_caching = false config.action_mailer.default_url_options = { host: 'localhost', port: 3000 }2.rootパスの設定
routes.rbにルーティングを記述
root to: '○○ #index'3.flashの設定
flashの作成はこちらでは説明を割愛するが
'app/views/layouts/application.html.erb'にflashを作れと言われている4.viewのカスタマイズ設定
deviseのviewをカスタマイズしたいならば以下を走らせろと言われているので、ターミナルで記述
rails g devise:viewsMODELの作成
設定が完了したら、modelの作成を行う
$ rails g devise Usermodelの作成が完了したらdb状態を更新する
$ rails db:migrate補足
必要であれば日本語化を行う
前提
application.rbファイルに以下を記述
config.i18n.default_locale = :jadeviseの日本語化
config/locales内に'devise.ja.yml'ファイルを作成し、以下のファイルをコピー
ja: activerecord: attributes: user: confirmation_sent_at: パスワード確認送信時刻 confirmation_token: パスワード確認用トークン confirmed_at: パスワード確認時刻 created_at: 作成日 current_password: 現在のパスワード current_sign_in_at: 現在のログイン時刻 current_sign_in_ip: 現在のログインIPアドレス email: Email encrypted_password: 暗号化パスワード failed_attempts: 失敗したログイン試行回数 last_sign_in_at: 最終ログイン時刻 last_sign_in_ip: 最終ログインIPアドレス locked_at: ロック時刻 password: Password password_confirmation: Password(確認用) remember_created_at: ログイン記憶時刻 remember_me: ログインを記憶する reset_password_sent_at: パスワードリセット送信時刻 reset_password_token: パスワードリセット用トークン sign_in_count: ログイン回数 unconfirmed_email: 未確認Eメール unlock_token: ロック解除用トークン updated_at: 更新日 models: user: ユーザ devise: confirmations: confirmed: メールアドレスが確認できました。 new: resend_confirmation_instructions: アカウント確認メール再送 send_instructions: アカウントの有効化について数分以内にメールでご連絡します。 send_paranoid_instructions: メールアドレスが登録済みの場合、本人確認用のメールが数分以内に送信されます。 failure: already_authenticated: すでにログインしています。 inactive: アカウントが有効化されていません。メールに記載された手順にしたがって、アカウントを有効化してください。 invalid: "%{authentication_keys}またはパスワードが違います。" last_attempt: もう一回誤るとアカウントがロックされます。 locked: アカウントは凍結されています。 not_found_in_database: "%{authentication_keys}またはパスワードが違います。" timeout: セッションがタイムアウトしました。もう一度ログインしてください。 unauthenticated: アカウント登録もしくはログインしてください。 unconfirmed: メールアドレスの本人確認が必要です。 mailer: confirmation_instructions: action: メールアドレスの確認 greeting: "%{recipient}様" instruction: 以下のリンクをクリックし、メールアドレスの確認手続を完了させてください。 subject: メールアドレス確認メール email_changed: greeting: こんにちは、%{recipient}様。 message: あなたのメール変更(%{email})のお知らせいたします。 subject: メール変更完了。 password_change: greeting: "%{recipient}様" message: パスワードが再設定されたことを通知します。 subject: パスワードの変更について reset_password_instructions: action: パスワード変更 greeting: "%{recipient}様" instruction: パスワード再設定の依頼を受けたため、メールを送信しています。下のリンクからパスワードの再設定ができます。 instruction_2: パスワード再設定の依頼をしていない場合、このメールを無視してください。 instruction_3: パスワードの再設定は、上のリンクから新しいパスワードを登録するまで完了しません。 subject: パスワードの再設定について unlock_instructions: action: アカウントのロック解除 greeting: "%{recipient}様" instruction: アカウントのロックを解除するには下のリンクをクリックしてください。 message: ログイン失敗が繰り返されたため、アカウントはロックされています。 subject: アカウントの凍結解除について omniauth_callbacks: failure: "%{kind} アカウントによる認証に失敗しました。理由:(%{reason})" success: "%{kind} アカウントによる認証に成功しました。" passwords: edit: change_my_password: パスワードを変更する change_your_password: パスワードを変更 confirm_new_password: 確認用新しいパスワード new_password: 新しいパスワード new: forgot_your_password: パスワードを忘れましたか? send_me_reset_password_instructions: パスワードの再設定方法を送信する no_token: このページにはアクセスできません。パスワード再設定メールのリンクからアクセスされた場合には、URL をご確認ください。 send_instructions: パスワードの再設定について数分以内にメールでご連絡いたします。 send_paranoid_instructions: メールアドレスが登録済みの場合、パスワード再設定用のメールが数分以内に送信されます。 updated: パスワードが正しく変更されました。 updated_not_active: パスワードが正しく変更されました。 registrations: destroyed: アカウントを削除しました。またのご利用をお待ちしております。 edit: are_you_sure: 本当によろしいですか? cancel_my_account: アカウント削除 currently_waiting_confirmation_for_email: "%{email} の確認待ち" leave_blank_if_you_don_t_want_to_change_it: 空欄のままなら変更しません title: "%{resource}編集" unhappy: 気に入りません update: 更新 we_need_your_current_password_to_confirm_your_changes: 変更を反映するには現在のパスワードを入力してください new: sign_up: アカウント登録 signed_up: アカウント登録が完了しました。 signed_up_but_inactive: ログインするためには、アカウントを有効化してください。 signed_up_but_locked: アカウントが凍結されているためログインできません。 signed_up_but_unconfirmed: 本人確認用のメールを送信しました。メール内のリンクからアカウントを有効化させてください。 update_needs_confirmation: アカウント情報を変更しました。変更されたメールアドレスの本人確認のため、本人確認用メールより確認処理をおこなってください。 updated: アカウント情報を変更しました。 updated_but_not_signed_in: あなたのアカウントは正常に更新されましたが、パスワードが変更されたため、再度ログインしてください。 sessions: already_signed_out: 既にログアウト済みです。 new: sign_in: ログイン signed_in: ログインしました。 signed_out: ログアウトしました。 shared: links: back: 戻る didn_t_receive_confirmation_instructions: アカウント確認のメールを受け取っていませんか? didn_t_receive_unlock_instructions: アカウントの凍結解除方法のメールを受け取っていませんか? forgot_your_password: パスワードを忘れましたか? sign_in: ログイン sign_in_with_provider: "%{provider}でログイン" sign_up: アカウント登録 minimum_password_length: "(%{count}字以上)" unlocks: new: resend_unlock_instructions: アカウントの凍結解除方法を再送する send_instructions: アカウントの凍結解除方法を数分以内にメールでご連絡します。 send_paranoid_instructions: アカウントが見つかった場合、アカウントの凍結解除方法を数分以内にメールでご連絡します。 unlocked: アカウントを凍結解除しました。 errors: messages: already_confirmed: は既に登録済みです。ログインしてください。 confirmation_period_expired: の期限が切れました。%{period} までに確認する必要があります。 新しくリクエストしてください。 expired: の有効期限が切れました。新しくリクエストしてください。 not_found: は見つかりませんでした。 not_locked: は凍結されていません。 not_saved: one: エラーが発生したため %{resource} は保存されませんでした。 other: "%{count} 件のエラーが発生したため %{resource} は保存されませんでした。"
- 投稿日:2020-09-13T14:11:19+09:00
curlコマンドでrailsAPIの操作
この記事について
初心者がAPI操作に役立ったコマンドを投稿する記事です。
curlコマンドとは
curlコマンドとはサーバから、もしくはサーバへデータ転送を行うコマンドです。
curl [options] [URL]学んだこと
#POST curl -i -X POST -H 'Content-Type: application/json' -d '{ "カラム名": "データ" }' localhost:3000/posts #UPDATE curl -i -X PUT -H 'Content-Type: application/json' -d '{ "カラム名": "データ" }' localhost:3000/posts/:id #DELTE curl -X DELETE localhost:3000/posts/:id
- 投稿日:2020-09-13T14:05:22+09:00
【RailsAPI×Docker】シェルで手軽に環境構築 & Flutterでも動作確認
初心者の方でも進められるよう手順は丁寧してあります。
やること
- RailsAPI × Docker での環境構築
- RailsAPIを軽く実装
- APIクライアントからAPIを叩く(PostmanやFlutterアプリから)※Flutterは任意で
APIコンテナ起動のシェルだけ見たい方 → こちら
一応 RailsAPIのソースコード、Flutterのソースコードも用意(※いじり倒してる可能性あり)手順
- API側のDockerコンテナ起動まで
- ディレクトリ作成
- シェルでRailsAPIコンテナビルド
- コンテナ起動&確認
- RailsAPI実装
- User モデル作成&DBテーブル用意
- User のコントローラ作成
- ルーティング設定
- PostmanでAPIの動作を確認
- Postmanインストール
GET
でDBのUserリソースを取得POST
でDBのUserリソースを追加- FlutterでAPIを叩く
- プロジェクト作成
- Http通信を行えるようにする
- main.dartを編集
前提
- AndroidStudioでFlutterアプリケーションを起動した状態にする
- SDKなどをダウンロードしてシミュレータを起動できる
- ※ Flutterセットアップはこちらの記事で基本全部いけました(3~40分はかかります)
- Docker, docker-compose のコマンドが使える(
$ docker-compose -v
が動けばOK)1. API側のDockerコンテナ起動まで
RailsAPIのDockerコンテナを作っていきます。
ただ、1からコマンドを打っていくのは非効率なので、基本的なところはシェルにまとめてあります。
1-1. ディレクトリ作成
app_name
にプロジェクト名を当てはめてディレクトリを用意します。$ mkdir app_name # APIアプリを置くディレクトリ用意 $ cd app_name1-2. シェルでRailsAPIコンテナビルド
以下がAPIコンテナのビルドまでやってくれるシェルです。(参考にした記事)
サンプルAPI立ち上げ用のシェル
set_up_rails.sh#!/bin/bash #config setting############# APP_NAME="app_name" # ← 自由に変更してください(ディレクトリ名と一緒がいいかも) MYSQL_PASSWORD="password" # ← 自由に変更してください ########################### echo "docker pull ruby2.6.6" docker pull ruby:2.6.6 echo "docker pull mysql:5.7" docker pull mysql:5.7 echo "docker images" docker images echo "make Dockerfile" cat <<EOF > Dockerfile FROM ruby:2.6.6 ENV LANG C.UTF-8 RUN apt-get update -qq && apt-get install -y build-essential libpq-dev nodejs #yarnのセットアップ RUN curl -o- -L https://yarnpkg.com/install.sh | bash ENV PATH /root/.yarn/bin:/root/.config/yarn/global/node_modules/.bin:\$PATH # 作業ディレクトリの作成、設定 RUN mkdir /${APP_NAME} ENV APP_ROOT /${APP_NAME} WORKDIR \$APP_ROOT # ホスト側(ローカル)のGemfileを追加する ADD ./Gemfile \$APP_ROOT/Gemfile ADD ./Gemfile.lock \$APP_ROOT/Gemfile.lock # Gemfileのbundle install RUN bundle install ADD . \$APP_ROOT # gem版yarnのuninstall rails6でエラーになるため RUN gem uninstall yarn -aIx #webpackerの設定 #RUN rails webpacker:install EOF echo "make Gemfile" cat <<EOF > Gemfile source 'https://rubygems.org' git_source(:github) { |repo| "https://github.com/#{repo}.git" } gem 'rails', '~> 6.0.3.2' EOF echo "make Gemfile.lock" touch Gemfile.lock echo "make docker-compose.yml" cat <<EOF > docker-compose.yml version: '3' services: db: image: mysql:5.7 environment: MYSQL_ROOT_PASSWORD: ${MYSQL_PASSWORD} MYSQL_DATABASE: root ports: - '3306:3306' api: build: . command: bundle exec rails s -p 3000 -b '0.0.0.0' volumes: - .:/${APP_NAME} ports: - '3000:3000' links: - db EOF echo "docker-compose run api rails new . --api --force --database=mysql --skip-bundle" docker-compose run api rails new . --api --force --database=mysql --skip-bundle echo "docker-compose run api bundle exec rails webpacker:install" docker-compose run api bundle exec rails webpacker:install docker-compose build # fix config/database.yml echo "fix config/database.yml" cat config/database.yml | sed "s/password:$/password: ${MYSQL_PASSWORD}/" | sed "s/host: localhost/host: db/" > __tmpfile__ cat __tmpfile__ > config/database.yml rm __tmpfile__ echo "docker-compose run api rails db:create" docker-compose run api rails db:createエディタからプロジェクト直下に新規ファイルとして作成&↑をコピペし、
set_up_rails.sh
などとして保存しましょう。「自由に変更してください」となっているapp_name
などは合わせて編集してください。保存が終わったら以下のようにシェルの権限を変更し、実行してみましょう(5分くらいかかります)。
$ chmod 755 set_up_rails.sh # 権限の変更 $ ./set_up_rails.sh # セットアップのシェル実行 docker pull ruby2.6.6 2.6.6: Pulling from library/ruby 57df1a1f1ad8: Pull complete 71e126169501: Pull complete 1af28a55c3f3: Pull complete ・ ・ ・シェルの実行が終わったら、
$ docker-compose ps
でコンテナの状態を確認してみましょう。以下のようになっていれば問題ないです。$ docker-compose ps Name Command State Ports ---------------------------------------------------------- app_name_db_1 docker- Up 0.0.0.0:3306-> entrypoint.sh 3306/tcp, mysqld 33060/tcp1-3. コンテナ起動 & 確認
次に、シェルでビルドしたコンテナを起動します。
$ docker-compose up rails-api-handson_db_1 is up-to-date Creating rails-api-handson_api_1 ... done Attaching to rails-api-handson_db_1, rails-api-handson_api_1 db_1 | 2020-09-12 08:27:00+00:00 [Note] [Entrypoint]: Entrypoint script for MySQL Server 5.7.31-1debian10 started. ・ ・ ・ api_1 | * Environment: development api_1 | * Listening on tcp://0.0.0.0:3000 api_1 | Use Ctrl-C to stop # ← これが出たらOK!Dockerコンテナのログが大量に出ますが、最後の
Use Ctrl-C to stop
が出ればコンテナが起動しているのでOKです。コンテナの起動が確認できたので、http://localhost:3000 にアクセスし、ちゃんとRailsとしてレスポンスを返してくれるか確認しましょう。以下のようになっていればAPIコンテナの動作は大丈夫です。
2. RailsAPI実装
動作確認用なので単純なユーザデータにしましょう。今回は、
User ( id, name, email )
みたいなリソースで実装してみます。
2-1. Userモデル作成 & DBテーブル用意
Userモデルとテーブルを用意します。
ここだけマイグレーションを使う方法とRidgepoleを使う方法に分けて紹介します(どちらも結果として同じモデル、スキーマが反映されます)。
Ridgepoleは、マイグレーションを使わずにスキーマを管理できるツールです。僕はこちらで進めていきますが、普段からマイグレーションを使っている方であればそちらで問題ありません。
パターン1) マイグレーションでモデル&テーブル作成
コンテナに入り、ジェネレータでUserモデルを作成。
$ docker-compose exec api bash # コンテナに入る # rails g model user name:string email:string # ↑ 出来なければ以後はBundle経由でやってみましょう( # bundle exec rails .... みたいな ) # exit # コンテナから出る(以後はコンテナの出入りは明記しません。 # コマンドラインの「$」や「#」で区別します。) $あとはマイグレーションをかけるだけです。
# rake db:migrateパターン2) Ridgepoleでモデル&テーブル作成
マイグレーションをスキップしてモデルを作成。
# rails g model user --skip-migration
プロジェクト直下にある
Gemfile
にgem 'ridgepole', '>= 0.8.0'
を追記します。mysql2の下とかで問題ないでしょう。Gemfilegem 'mysql2', '>= 0.4.4' # 元々ある gem 'ridgepole', '>= 0.8.0' # これを追加追記したgemをインストール。
# bundle install
次に
db/
のなかに、Schemafile.rb
というファイルを作成します(Ridgepoleではスキーマをここで一元管理する)。
db/Schemafile.rb
には以下のように書き、保存します。db/Schemafile.rbcreate_table "users", force: :cascade, options: "ENGINE=InnoDB DEFAULT CHARSET=utf8" do |t| t.string "name" t.string "email" t.timestamps endridgepoleのコマンドでスキーマファイルを反映。
# bundle exec ridgepole --config ./config/database.yml --file ./db/Schemafile.rb --apply Apply `./db/Schemafile.rb` -- create_table("users", {:options=>"ENGINE=InnoDB DEFAULT CHARSET=utf8"}) -> 0.0716s2-2. User のコントローラ作成
こちらの記事を参考に、URIにAPIのメジャーバージョン(v1.3なら1の部分)を含めます。ただこの記事だと、URIに
api
というネームスペースを使っています。これは僕個人の意見ですが、URIに
api
と明記するよりも、サブドメインなどで示した方がいいのでは?と思います。APIを使おうとするクライアントからすればAPIだってことはわかっていますから。example.com/api/vi/users # URIでapiだと示す api.example.com/vi/users # サブドメインで示すでは本題のコントローラ作成に戻ります。
コントローラの前に、メジャーバージョンを示す
v1/
を作成し、その中でusersコントローラを作成します。$ mkdir app/controllers/v1 $ rails g controller v1::usersコントローラファイルの中身は以下の感じです。
*/v1/users_controller.rbclass V1::UsersController < ApplicationController before_action :set_user, only: [:show, :update, :destroy] def index users = User.order(created_at: :desc) render json: { status: 'SUCCESS', message: 'Loaded user', data: users } end def show render json: { status: 'SUCCESS', message: 'Loaded the user', data: @user } end def create user = User.new(user_params) if user.save render json: { status: 'SUCCESS', data: user } else render json: { status: 'ERROR', data: user.errors } end end def destroy @user.destroy render json: { status: 'SUCCESS', message: 'Deleted the user', data: @user } end def update if @user.update(user_params) render json: { status: 'SUCCESS', message: 'Updated the user', data: @user } else render json: { status: 'SUCCESS', message: 'Not updated', data: @user.errors } end end private def set_user @user = User.find(params[:id]) end def user_params params.require(:user).permit(:name, :email) end end2-3. ルーティング設定
config/routes.rb
を以下のようにします。config/routes.rbRails.application.routes.draw do namespace 'v1' do resources :users end end↑が終わると、
rake routes
コマンドでルーティングが確認できるはずです。以下のようなルーティングが反映されていればOKです。# rake routes Prefix Verb URI Pattern Controller#Action v1_users GET /v1/users(.:format) v1/users#index POST /v1/users(.:format) v1/users#create v1_user GET /v1/users/:id(.:format) v1/users#show PATCH /v1/users/:id(.:format) v1/users#update PUT /v1/users/:id(.:format) v1/users#update DELETE /v1/users/:id(.:format) v1/users#destroy3. PostmanでAPIの動作を確認
Postmanとは、WebAPIのテストクライアントサービスのひとつです。APIの動作確認にはこれを使います。
3-1. Postmanインストール
公式サイトで、Postmanをインストールします。前にインストールしたのであまり覚えていませんが、登録して進めていけばOKだった気がします...。
Postmanインストール後、まずはコンソールで適当にUserのレコードを用意しておきましょう。以下のような感じでいいかと思います。
# rails c Loading development environment (Rails 6.0.3.3) irb(main):001:0> User.create(name: "hoge", email: "hoge@example.com")3-2.
GET
でDBのUserリソースを取得Postmanで以下のように
GETメソッド
、URI
を指定し、Send
ボタンを押します。すると、画面下のBodyで返ってきたレスポンスのBodyが確認できます。ここまでできていればAPIの動作確認としては成功です!
3-3.
POST
でDBのUserリソースを追加今度は以下のように、
POSTメソッド
を指定し、リクエストBodyの中にもデータを含めてみましょう。この時、形式がJSON
になっているか確認しましょう(画像の"JSON"とオレンジになっているところ)。成功すれば、登録されたUserのレコードがレスポンスBodyから確認出来ます。
ここで先ほどの
GETメソッド
でのアクセスをもう一度行ってみると、POST
メソッドで追加したレコードも一緒に確認できます。4. FlutterでAPIを叩く
結果こんな感じ
- アプリを起動したらDBにあるユーザのデータを表示
- 右下の
Add
ボタンでユーザデータの登録動作確認なのでミニマムな感じです。
4-1. プロジェクト作成
File > New > New Flutter Project...
からFlutterプロジェクトを作成します。iPhoneやAndroidのシミュレータ(エミュレータ)などが起動できていればOKです。4-2. Http通信を行えるようにする
デフォルトだとhttpを行うパッケージのimportでエラーを起こすので少し操作が必要になります。
まず、
pubspec.yaml
のdependencies:
に以下のように追記します。pubspec.yaml# ~ 省略 ~ dependencies: http: ^0.12.0 # ← 追加する flutter: sdk: flutter # ~ 省略 ~すると、Android Studioのエディタの上の方に、以下のようなFlutterコマンドが出てきます。今回は
Pub get
を選択します。もしこの先の作業でHttp周りのエラーが出るようであれば、僕が参考にしたこちらの記事も見てみるといいかも知れません。
4-3. main.dartを編集
動作確認をしたいだけであれば、
lib/main.dart
を以下のように書き換えれば動きます。なお、僕はFlutterは初歩の初歩なので物申すことがあればコメントにお願いします。
lib/main.dartimport 'dart:async'; import 'dart:convert'; import 'package:flutter/material.dart'; import 'package:http/http.dart' as http; void main() => runApp(MyApp()); class MyApp extends StatefulWidget { MyApp({Key key}) : super(key: key); @override _MyAppState createState() => _MyAppState(); } class _MyAppState extends State<MyApp> { Future<GetResults> res; @override void initState() { super.initState(); res = getUsers(); } // postUser()でUserを登録。setState内で再度User一覧を取得 void _postUser() { postUser(); setState(() { res = getUsers(); }); } @override Widget build(BuildContext context) { return MaterialApp( title: 'APIをPOSTで呼び出しJSONパラメータを渡す', theme: ThemeData( primarySwatch: Colors.yellow, ), home: Scaffold( appBar: AppBar( title: Text('RailsAPI x Flutter'), ), body: Center( child: FutureBuilder<GetResults>( future: getUsers(), builder: (context, snapshot) { if (snapshot.hasData) { return Text( snapshot.data.message.toString() ); } else if (snapshot.hasError) { return Text("${snapshot.error}"); } return CircularProgressIndicator(); }, ), ), floatingActionButton: FloatingActionButton( onPressed: _postUser, tooltip: 'Increment', child: Icon(Icons.add), ), ), ); } } class GetResults { final String message; GetResults({ this.message, }); factory GetResults.fromJson(Map<String, dynamic> json) { var datas = ''; json['data'].forEach((item) => datas += 'id: ' + item['id'].toString() + ', name: ' + item['name'] + ', email: ' + item['email'] + '\n'); return GetResults( message: datas, ); } } class PostResults { final String message; PostResults({ this.message, }); factory PostResults.fromJson(Map<String, dynamic> json) { return PostResults( message: json['message'], ); } } class SampleRequest { final String name; final String email; SampleRequest({ this.name, this.email, }); Map<String, dynamic> toJson() => { 'name': name, 'email': email, }; } Future<GetResults> getUsers() async { var url = 'http://127.0.0.1:3000/v1/users'; final response = await http.get(url); if (response.statusCode == 200) { return GetResults.fromJson(json.decode(response.body)); } else { throw Exception('Failed'); } } Future<PostResults> postUser() async { var url = "http://127.0.0.1:3000/v1/users"; // APIのURI var request = new SampleRequest(name: 'foo', email: 'foo@example.com'); // Userのパラメータ。自由に変更してOK final response = await http.post(url, body: json.encode(request.toJson()), headers: {"Content-Type": "application/json"}); if (response.statusCode == 200) { return PostResults.fromJson(json.decode(response.body)); } else { throw Exception('Failed'); } }シミュレータを起動すると、、登録されたUserがきちんと返ってきてますね!
右下のAddボタンを押すと、、
main.dart
で指定したUserデータが登録され、取得できているのも確認できました!終わり
質問やご指摘があればコメントにお願いします。
- 投稿日:2020-09-13T13:52:01+09:00
Railsで使用するワンライナーの個人的なまとめ
概要
Railsで使用するワンライナーの個人的なまとめ
routes情報を出力
使用シーン
railsコマンドのroutesを使用すると4つの情報が表示される。
Prefix , Verb, URI Pattern, Controller#Action//routesの実行 $ ./bin/rails routes //結果の出力---- Prefix Verb URI Pattern Controller#Action users POST /v1/users(.:format) users#create user GET /v1/users/:id(.:format) users#show ...この出力情報を加工して、稀にパス情報(URI Pattern)だけ抜き出したい場合がある。
// v1 から始まる パス文字列のみが欲しい場合 $ ./bin/rails routes |grep v1 |awk -F " " '{ print $(NF-1)}' // 結果の出力ーーーーーーー /v1/users(.:format) /v1/users/:id(.:format) ... // Verbも含んで結果を出したい場合 ./bin/rails routes |grep v1 |awk -F " " '{ print $(NF-2) " " $(NF-1)}' POST /v1/users(.:format) GET /v1/users/:id(.:format) ...解説
1. 結果リストをv1のみに絞っている(絞る文字は任意で変更)
2. awk -F " " で スペース(" ")をセパレータに指定している。
3. print $(NF-1) で NF(末尾)から1文字目を printしている。(末尾から指定するのがポイント。でないとズレる)ここに、sortしたりするとざっくりのエンドポイントの一覧が得られる。
- 投稿日:2020-09-13T12:10:04+09:00
Rails Tutorial 第13章 S3のエラー以外は完了
2020/8/30 1.5時間
13.1.3まで進めました。
2020/8/31 0.5時間
13.16まで進めました。
2020/9/1 0.5時間
13.21まで進めました。
2020/9/2 0.5時間
13.22まで進めました。
2020/9/3 2.0時間
有給休暇で、13.29まで進めました。
2020/9/4 0.5時間
13.2.3.2まで進めました。
2020/9/5 2.5時間
休みの日で、13.3.1まで進めました。
2020/9/6 1.5時間
休みの日で、13.3.4まで進めました。
2020/9/7 0.5時間
13.55まで進めました。
2020/9/8 0.5時間
13.3.5.1まで進めました。
2020/9/9 0.5時間
13.3完了です。
2020/9/10 2.0時間
有給休暇で、13.63まで進めました。
Cloud9のディスクが不足でgemのinstallができず、ディスクを拡張しました。2020/9/11 0.5時間
13.4.2完了です。
2020/9/12 4.0時間
休みの日で、13.4.3完了です。
ImageMagickのインストールエラーで時間をとられました。さらにAWS S3のエラーで2時間ほどはまり、この日はあきらめました。2020/9/13 1.5時間
休みの日で進めました。S3のエラーは根本は解決しませんでしたが、そのまま進めました。
13章を完了です。
所要時間は19.0時間です。cloud9でyumがないためImageMagickがインストールできない
ubuntu:~/environment/sample_app (user-microposts) $ sudo yum install -y ImageMagick sudo: yum: command not foundyumがないとエラー、Ubuntuではyumではなくaptのようです。
ネットで調べ、apt-getを入力します。ubuntu:~/environment/sample_app (user-microposts) $ sudo apt-get update ubuntu:~/environment/sample_app (user-microposts) $ sudo apt-get install imagemagick Reading package lists... Done Building dependency tree Reading state information... Done You might want to run 'apt --fix-broken install' to correct these. The following packages have unmet dependencies: imagemagick : Depends: imagemagick-6.q16 (>= 8:6.9.2.10+dfsg-2~) but it is not going to be installed linux-headers-5.3.0-1034-aws : Depends: linux-aws-5.3-headers-5.3.0-1034 but it is not going to be installed linux-image-5.3.0-1034-aws : Depends: linux-modules-5.3.0-1034-aws but it is not going to be installed E: Unmet dependencies. Try 'apt --fix-broken install' with no packages (or specify a solution).エラーがでたので、メッセージにあるTryの後のコマンドを入力してみたところ、無事できました。
ubuntu:~/environment/sample_app (user-microposts) $ sudo apt --fix-broken install ..done ubuntu:~/environment/sample_app (user-microposts) $ sudo apt-get install imagemagick演習13.4.4.2 エラーがでると書いてあるが、エラーはでなかった
テキストではtestでエラーがでると書いてありますが、エラーはでませんでした。rails.pngが小さくて縮小されないのではと思い、ダウンロードしてみたところ、凄く小さいアイコンファイルでした。サイズが大きいファイルで置き換えてみましたが、エラーはでません。
リスト13.68のファイルを作ってみましたが、結果が変わらないのでこのファイルが効いているのかも分かりませんでした。
- 投稿日:2020-09-13T11:42:24+09:00
【Rails】content_tagを解説してみる。
忘備録的に書いていきます。間違っている点などありましたら、コメントしていただけるとありがたいです?♂️
【概要】content_tagとは
- Railsのview helperで使われる。
- HTMLコードの要素を生成することができる。
【何が嬉しいのか?】
HTMLコードを直に書くとセキュリティ面で脆弱性が出てしまうことがある。(XSS,CSRFであったり。)
上記のようなことを防ぐために、Railsに乗っていく(
content_tag
を使う)とセキュリテイ面で恩恵を受けることができます。
HTML
とerb
がごちゃごちゃになってしまう場合に整理して書けるというメリットもあります。小さくパーシャル化するのにも使えるかもしれませんね。
【基本的な使い方】
content_tag :p, 'Hello, World!' # => <p>Hello, World!</p>第一引数にタグを指定し、第二引数に
content
となる部分を埋め込む。ちなみに、第二引数にはシンボル(
:p
みたいな)だけではなく、文字列も許容してくれるcontent_tag 'p', 'Hello, World!' # => <p>Hello, World!</p>少し、実践的な書き方をするとこんな感じ???
content_tag :p, @user.name # => <p>佐藤</p>「こんなこともできるよ」集
HTMLオプションはハッシュで
content_tag :p 'Hello' class: 'hoge' # => <p class='hoge'>Hello</p>こんな感じで
class
を持たせることもできます。ちなみに、複数のclass
を持たせるには下記のように書けばOKcontent_tag(:p, 'Hello', class: ["hoge", "foo"]) # => <div class="hoge foo">Hello</div>ネストもできるよ
content_tag :div do content_tag :p @user.name content_tag :p @user.age endこんな感じにネストして書くこともできる。
おいおい、#tagって知ってるか??
下記はみんな大好きDHHのissueです。
https://github.com/rails/rails/issues/25195
content_tag :span, nil, class: 'bookmark' # 下記は上記と同じ意味 tag.span class: 'bookmark'すごい直感的に書けるようになりましたよね。
色々変わったのですが、個人的には下記がお気に入り。
tag.div(id: 'header') { |tag| tag.span 'hello' } # <div id="header"><span>hello</span></div>でも、下記も簡潔に書けますよね。
<%= tag.p do %> hoge <% end %>特に理由がなれば、
content_tag
ではなく、tag
を使うと可読性が上がるかな〜と思いました。参考関連記事
https://qiita.com/ren0826jam/items/0ebd451d1da90e496c2f
https://makicamel.hatenablog.com/entry/2019/03/07/224552
https://techracho.bpsinc.jp/hachi8833/2018_11_01/48191
- 投稿日:2020-09-13T10:01:17+09:00
Rails 6で認証認可入り掲示板APIを構築する #8 seed実装
←Rails 6で認証認可入り掲示板APIを構築する #7 update, destroy実装
seedとは
開発中にテストデータが必要な時、都度
rails c
やらcreate actionを叩いてレコード作るのは手間です。
そこで、コマンドを叩くだけであらかじめ設定しておいたレコードを、50だろうが1000だろうが簡単に作れるseedを取り入れます。ファイル作成とロード
rails seedだけでググると大抵db/seeds.rbに直書きばかり出てきますが、modelが多くなると管理がしづらくなります。
そこでファイルを分割し、db/seeds.rbからrequireで呼ぶ形式にします。こうすることで追加削除時の管理がしやすくなりますし、seedはファイル指定で実行することもできるので便利です。
$ mkdir db/seeds $ touch db/seeds/post_seeds.rbdb/seeds.rb# frozen_string_literal: true seed_models = %i[post] seed_models.each do |model| require "./db/seeds/#{model}_seeds" enddb/seeds/post_seeds.rb# frozen_string_literal: true unless Post.exists? 20.times do Post.create!(subject: "hoge", body: "fuga") end end今後seed対象のmodelが増えることを予想し、seed_modelsという変数に追加していくことで外部ファイル読み込みをするようにします。
ディレクトリ走査することで都度db/seeds.rbを変更しなくても良い作りにできるのですが、postモデルの前に今後作るuserモデルのレコードが存在していないといけない等の依存関係が発生するので、手動で実行順を弄れるように書いています。post_seeds.rbの中身は単純に
Post.create!
を20回実行しているだけです。
!
を付けることによりバリデーションエラーで登録できなかった際に例外が投げられるので、気付いたらレコードが生成されていなかった事態を防げます。$ rails db:reset $ rails db:seed $ rails c [1] pry(main)> Post.count (1.1ms) SELECT COUNT(*) FROM "posts" => 20db:resetすることでテーブルを全dropし再生成。これでレコードがある時のみ動くseedが実行されます。
そしてdb:seedすることで、20レコードが追加されていることが確認できます。Fakerの導入
レコードができたのはいいのですが全部subjectがhoge, bodyがfugaになっています。
このままだと、何かしらの原因でAPIから取得したら同一レコードが紛れていたりしても気付きづらくなります。
とはいえ完全ランダムな文字列を都度作るのも手間だし…ということで、役立つのがFakerです。とりあえず入れてみましょう。
Gemfile... group :development, :test do ... + "faker" end ...$ bundle試しに使ってみましょう。
$ rails c [1] pry(main)> Faker::Name.unique.name => "Miss Porter Kovacek" [2] pry(main)> Faker::Name.name => "Felicita Durgan" [3] pry(main)> Faker::Name.name => "Yong Weissnat" [4] pry(main)> Faker::Name.name => "Sandie Oberbrunner"こんな感じに、実行のたびにランダムな名詞や文章を自動で返してくれるものです。
デフォルトで定義されている語句はGithubで確認すると良いです。
人名や動物、住所や電話番号等だけでなく、映画、漫画、ゲーム、ドラマ、音楽なんかもあります。ポケモン名とかONE PIECEの悪魔の実とかまでありますね。seedsにFakerを入れる
db/seeds/post_seeds.rb# frozen_string_literal: true unless Post.exists? 20.times do - Post.create!(subject: "hoge", body: "fuga") + Post.create!(subject: Faker::Lorem.word, body: Faker::Lorem.paragraph) end end$ db:reset $ db:seed $ rails c [1] pry(main)> Post.all Post Load (0.4ms) SELECT "posts".* FROM "posts" => [#<Post:0x000000000636cbe8 id: 1, subject: "quos", body: "Earum numquam qui. Impedit autem molestias. Ipsum adipisci eos.", created_at: Sun, 06 Sep 2020 15:36:27 UTC +00:00, updated_at: Sun, 06 Sep 2020 15:36:27 UTC +00:00>, #<Post:0x00000000063b5be0 id: 2, subject: "vero", body: "Impedit distinctio saepe. Adipisci cupiditate officiis. Vel et deleniti.", created_at: Sun, 06 Sep 2020 15:36:27 UTC +00:00, updated_at: Sun, 06 Sep 2020 15:36:27 UTC +00:00>,ランダムなsubject, bodyのレコードができていることが確認できます。
Fakerを日本語化する
せっかく入れたのに英語だと日本語サイトを作る上で不便なので、ローカライズしましょう。
db:seedはdev環境で実行するので、dev環境の時にFakerを日本語化してみます。config/environments/development.rbRails.application.configure do ... + Faker::Config.locale = "ja" end常に日本語化が嫌なのであれば、
Faker::Config.locale = "ja"
をdb/seeds/post_seeds.rbに入れてもOKです。
その後再度seedを実行します。$ rails db:reset $ rails db:seed $ rails c [1] pry(main)> Post.all Post Load (0.3ms) SELECT "posts".* FROM "posts" => [#<Post:0x0000000006480b88 id: 1, subject: "いく", body: "警官総括大尉。めいしぼきんかたみち。伝統徳川超〜。", created_at: Sun, 06 Sep 2020 15:45:27 UTC +00:00, updated_at: Sun, 06 Sep 2020 15:45:27 UTC +00:00>, #<Post:0x00000000064fb928 id: 2, subject: "フランス語", body: "〜系けいかん先週。うえる自宅そだてる。店舗にんい高値。", created_at: Sun, 06 Sep 2020 15:45:27 UTC +00:00, updated_at: Sun, 06 Sep 2020 15:45:27 UTC +00:00>,無事に日本語化されていますね。
なお、日本語化されているものはGithubで確認できます。逆に言えばこの中に無いものは英語のままです。続き
- 投稿日:2020-09-13T06:20:48+09:00
Rails uninitialized constant エラーの解決へのシンプルなチェックリスト
これはなにか
Railsをそれなりにやっているにも関わらず、uninitialized constant error にハマってしまったのでチェックリストをここにまとめておこうと思う。
結論
チェックするべき項目は以下3点である。
- ファイル名とclass名が一致しているか?
- ファイルpathとmoduleの定義が一致しているか?
- Railsにファイルを読み込ませているか?
以下詳細をかいていく。
ファイル名とclass名が一致しているか?
以下のようなclassが存在していたら、ファイル名は
qiita_user.rb
でないといけない。class QiitaUser def hoge end endファイルpathとmoduleの定義が一致しているか?
以下のようなmoduleにnestされたclassが存在していたら、pathは
**/v1/auth/user.rb
のようになるだろう。class V1::Auth::User endOR
module V1 module Auth class User end end endRailsにファイルを読み込ませているか?
Railsのデフォルトのフォルダ以外に、フォルダを追加する場合、autoload pathに追加したフォルダへのpathを定義する必要がある。
app/lib/hoge/foo.rb
を追加したとする。この場合、config/application.rb
に以下の様な形で、autoload pathを追加する必要がある。module App class Application < Rails::Application # 省略 config.autoload_paths += Dir.glob("#{config.root}/app/lib") end end
- 投稿日:2020-09-13T02:03:49+09:00
slimの長い構文を途中で改行する
Railsアプリ開発時にslimを使ってhtmlを書いているときに、このような長い構文がある。これを改行する方法。
.card-toolbar a.btn.btn-primary.status-editable data-confirm="全ユーザーの編集権限を「編集可」に変更します。よろしいですか?" style="font-size: 15px; margin: 0 10px;" href="#{toggle_status_editable_admins_supplier_company_path(supplier_company_code: model.code, supplier_company_id: model.id)}" role="button" 編集可 a.btn.btn-danger.status-editable data-confirm="全ユーザーの編集権限を「編集可」に変更します。よろしいですか?" style="font-size: 15px; margin: 0 10px;" href="#{toggle_status_not_editable_admins_supplier_company_path(supplier_company_code: model.code, supplier_company_id: model.id)}" role="button" 編集不可こんな感じで[]をつけて改行できる。
.card-toolbar a[data-confirm="全ユーザーの編集権限を「編集可」に変更します。よろしいですか?" style="font-size: 15px; margin: 0 10px;" href="#{toggle_status_editable_admins_supplier_company_path(supplier_company_code: model.code, supplier_company_id: model.id)}" role="button"] .btn.btn-primary.status-editable | 編集可 a[data-confirm="全ユーザーの編集権限を「編集不可」に変更します。よろしいですか?" style="font-size: 15px; margin: 0 10px;" href="#{toggle_status_not_editable_admins_supplier_company_path(supplier_company_code: model.code, supplier_company_id: model.id)}" role="button"] .btn.btn-danger.status-editable | 編集不可
- 投稿日:2020-09-13T02:00:46+09:00
[Rails]外部キー制限かかっているときにdestoryできないエラーを発生させたい時の対処
はじめに
レコード削除時に関連づけられたレコードが存在するときに、例外やエラーを発生させたい。
外部キーで使用されていると親要素が消されては困るというシチュエーションです。削除しようとするとRubyのエラー画面が出てしまう。
原因
Model
に関係づけされたモデルに対する挙動を定義するが無いからでした。
マイグレーションファイルのforeign key: True
だけでは不十分でした。対策
Model
にdependentオプション
を記述することで解決しました。
該当のモデルに以下の記述をします。#contractというモデル class Contract < ApplicationRecord has_many :...., dependent: :restrict_with_error endアソシエーション記述の後に
dependent: :restrict_with_error
と記述することでdestory
できないときのエラーを表示することができた。
以下の条件分が成り立ち解決しました!。#contractというモデルのコントローラー def destroy contract = Contract.find(params[:id]) if contract.destroy redirect_to contract_path, notice: "選んだ契約を削除しました" else redirect_to contract_path, alert: "使用中のため削除できません" end end参照
・https://dorarep.page/articles/rails-dependent#dependent_restrict_with_exception_restrict_with_error
- 投稿日:2020-09-13T01:42:37+09:00
[Rails]errorsメソッドでメッセージ表示させるとビューが崩れる時の対処
はじめに
form
で入力に誤り(例えば無入力)があるとエラーメッセージを表示させるためにerrorsメソッド
を用いて記述し、動きを確認するとビューが崩れるという問題が発生しました。その時の自分の解決した方法です。原因
崩れたビューを確認すると
field_with_errors
というdivクラス
が付与させていていることを確認した。これが原因である。対処
今回はこの
field_with_errors
というdivクラス
が付与されないようにした。
config/application.rb
に以下の記述をした。module #モデル名 class Application < Rails::Application config.load_defaults 6.0 config.i18n.default_locale = :ja config.action_view.field_error_proc = Proc.new { |html_tag, instance| html_tag } #↑この記述をプラスした end endこうすることで余計なクラスが付与されずにできました!
参考
- 投稿日:2020-09-13T01:29:25+09:00
[Rails]errorsメソッドでエラーメッセージが出せないときの対処
はじめに
例えば
result.save
のように変数result
の保存をしようとした時に、失敗するとresultにエラーメッセージが格納される。
これを利用してエラーメッセージを表示させたいがRubyのエラー画面となる。言い換えると思い通りのエラーメッセージが出ない。
エラー時にコンソールで確認の以下のようになる
result.errors.any? => False保存できてないのにエラー出てないことになってる。
今回は無入力で登録しようとするとエラーを出したい。
原因
Model
にバリデーション記述が無かったことが原因。
テーブル作成時にはカラムに制限(無入力制限のためnull: false
とした)がそれだけではエラーメッセージがでない。対策
Model
に以下のような記述をした。class Result < ApplicationRecord belongs_to ... has_many ... validates :name, presence: true ... end
validates :name, presence: true
と記述することでresult.errors.any? => Trueとなり
result.errors.full_messagesで、エラーメッセージ全件の内容を取得し
each
を用いて取り出せました!