- 投稿日:2019-10-08T23:51:02+09:00
自分用メモ(editとDelete)
Edit
edit_post_path(post)
→postオブジェクトを渡しているので、post.idを渡している(Railsはオブジェクトを一意に表す値を取得しようとするから)
→/posts/id/というようなパスが生成bundle install と bundle updateの違い
「前提」
(設計図)gemfile・・・gemfileに書くもの全ては書いてない
90記載↓設計図を元に作るーbundler(gemfileに書いてないもの残り10を取ってくる)
(設計した結果)gemfile.lock
100記載「bundle update」
gemfileを元に
↓
bundle update
↓
gemfile.lockを更新「bundle install」
A,B,Cをgemとする。Bのアップデート後をB'とする。
gemfileにA,B,C
gemfile.lockにA,B'が記載されているとするgemfile.lock
↓
bundle install
gemfile.lockに書かれている A,B'のgemをインストール
gemfile.lockに書かれていなくて、gemfileに書かれているgem Cをインストール
↓
gemfile.lockを更新→gemfile.lockにもともと記載されていたgemはアップデートされない
bundle install とbundle updateの使い分け
新しい環境に変わった・新しくgemfileに新しくgemを記載した(ローカル環境で行う)
↓
bundle install
※本番環境で行うと、gemが更新されクラッシュするので注意
ーーーーgemのバージョン更新
↓
bundle update参考
https://qiita.com/lasershow/items/1a048d03ddaaba98171eユーザーmodel作成
メルアドはデータベースレベルで一意性を保ちたいので、indexつけて、それをunique: trueにする
bcryptとpassword_digest作ったら
models/user.rb にhas_secure_passwordを書く
→仮想属性password と password_confirmationが作られるDB
疑問↓
データベース単位で受け取れる値を決めた方が良いのか(db:migrate前でデータの制約)
データ送信時にデータを検証した方が良いのか
- 投稿日:2019-10-08T22:41:32+09:00
【Rails】viewにおけるページタイトルの扱い方
開始タグ
ページタイトルの存在がすっぽ抜けていたので設定しました。
方法
ページタイトル例:
ログイン画面|テストアプリ
最初に
/app/views/layouts/
内にある何かのテンプレート内の<title></title>
の中に以下を記述。application.html.erb<title> <%= content_for?(:html_title) ? yield(:html_title) : "" %> |テストアプリ </title>最後に
/app/views/
以下のビューファイルに以下を記述。login.html.erb<% content_for(:html_title) { 'ログイン画面' } %>簡単2STEP!
自分は究極にざっくりとこう解釈。
○
content_for
=コンテンツを1箇所にまとめて他のビューでも使用できるようにしてるんじゃない?
○yield(:html_title)
=yield
とあるから、ビューファイルにcontent_for(:html_title)
があればそこから持ってくるんじゃない?閉じタグ
「全然仕組み分かってないなー!」と文字に起こそうとする思い知らされますね。
「知らなければ知ればいい」と自分を励ましておきます。参考サイト
ActionView::Helpers::CaptureHelper(リファレンス)
Rails: ページタイトルはビューテンプレートのcontent_forで表示すること(翻訳)
- 投稿日:2019-10-08T21:58:45+09:00
Date.today.since(7.days) ←7日後
何日後:since
何日前:ago
どちらも`Dateクラスが持っているメソッドである。
[1] pry(main)> Date.today => Tue, 08 Oct 2019 [2] pry(main)> Date.today.since(3.days) => Fri, 11 Oct 2019 00:00:00 JST +09:00 [3] pry(main)> Date.today.ago(3.days) => Sat, 05 Oct 2019 00:00:00 JST +09:00
- 投稿日:2019-10-08T21:51:56+09:00
【Rails】RSpecでモデルのテストをする
概要
モデルのテストの記述方法を解説します
詳しくはRSpecの公式サイトのモデルに関するページを参考にしてください
今回は一例としてPostモデルのテストを解説します。
前提としてPostにはアソシエーションされたCommentモデルが存在します。spec/models/post_spec.rbrequire "rails_helper" RSpec.describe Post, :type => :model do context "with 2 or more comments" do it "orders them in reverse chronologically" do post = Post.create! comment1 = post.comments.create!(:body => "first comment") comment2 = post.comments.create!(:body => "second comment") expect(post.reload.comments).to eq([comment2, comment1]) end end end基本はRubyの書き方と同じです。コントローラーの記述する感覚で書きます。
post = Post.create!
- postを作成、保存します
create
メソッドはnew
+save
です!
をつけると保存できなかった時にその原因を出力してくれます
comment1 = post.comments.create!(:body => "first comment")
post
に紐づいたcomment
を:body => "first comment"
で作成する- comment2も同様です
expect(post.reload.comments).to eq([comment2, comment1])
post.reload.comments
の値が[comment2, comment1]
と一致するかどうかを確かめるpost.reload.comments
のreload
はデータベースの値を再び取得するためのメソッドです以上がモデルのテストの記述方法の一例の解説です。
これを元に自身のアプリケーションにも適応し、テストしてみてください。疑問、気になるところがございましたら、質問、コメントよろしくお願いいたします!!
- 投稿日:2019-10-08T18:49:33+09:00
Railsでタイムゾーンを使う場合の注意点まとめ
記事の概要
- 標準時・タイムゾーンの定義を確認
- Railsでのタイムゾーン設定箇所と注意点の確認
動作確認した環境
- rails 5.2.1
タイムゾーンという概念
標準時・タイムゾーンとは何か
ある地域で共通している時刻系をその国の標準時と呼びます。
例えば日本ではJST (Japan Standard Time) と言う標準時を採用しています。
今がAM 10:00 なら沖縄でも北海道でも同じくAM 10:00 になります。これは日本国内ではどの地域もJSTを採用しているためです。標準時と言う時刻系が共通している地域全体のことをタイムゾーンと言います。
標準時の適用範囲
標準時の適用範囲は、便宜上、国または地域という単位になっています。
日本が昼間の時に夜の国があるように、天体的な問題(地球の自転や太陽との関係性など)から地球全域で同じ時間帯を採用することはできません。
逆に、太陽がちょうど真南にくることを意味する南中を基準に各地で正午を観測するような細かさだと、それぞれの経度ごとに標準時ができてしまいます。それだといろいろ不便(例えば国内だと関東と東北でいちいち小さな時差があるのはめんどくさい)なので、地理的にある程度近い地域では共通の時刻を使いましょうということになってます。
この地域というのは必ずしも国とは限りません。
アメリカのような国土が広大な国だったり離島があったりする国では地方によって採用している標準時が異なったりします。逆に地理的に近ければ、国が違っても時差がない場合があります。
日本と韓国は時差がありません。日本ではJST、韓国ではKSTという標準時をそれぞれ採用していますが、これは呼び方が違っても時刻系としては同じものになります。オフセットは協定世界時(UTC)
標準時やタイムゾーンは協定世界時(UTC)を基準に何時間進んでいるか or 遅れているかで表現されます。
日本標準時(JST)は協定世界時(UTC)より9時間進んでいるので +09:00 というような表記になります。Railsでのタイムゾーン設定
海外展開(異なるタイムゾーンをまたがって)展開しているようなアプリであれば標準時やタイムゾーンの理解が必要になります。
タイムゾーンの設定というのはOSやRailsのアプリケーションで各々持っていて、あるオブジェクトではOSのタイムゾーンを参照、他方ではアプリケーションの設定を参照しているケースなどがあり、その上アプリとは別にデータベースのタイムゾーンも設定が別れていたりします。
このようなややこしさから躓石となりやすい箇所です。Railsアプリを実装する上で考慮すべき設定は以下です。
- OSのタイムゾーン設定
- アプリケーションのタイムゾーン設定
- アプリケーションがデータベースをどのタイムゾーンで扱うかの設定
各々の設定場所や概略などは下表のとおりです。
※表中の「設定ファイル」はここでは config/application.rb で、既定値はrails 5.2.1でのものとします
設定場所 概略 既定値 1. OSのタイムゾーン /etc/localtime (UNIX系OSの場合) Rubyの組み込みクラスがこの値を参照する - 2. アプリケーションのタイムゾーン 設定ファイルの config.time_zone ActiveSupport::TimeWithZoneがこの設定値を参照する UTC 3. アプリケーションがデータベースを… 設定ファイルの config.active_record.default_timezone RailsがActiveRecordを通してデータベースに時刻を保存する、または取り出す際に値をどのタイムゾーンとして扱うかの設定 nil ゞ 設定ファイルの config.active_record.time_zone_aware_attributes ActiveRecordのインスタンスに時刻型のプロパティがあったときにどう扱うかの設定 - 以下、各々に関して詳しく見ていきます。
1. OSのタイムゾーン
OS毎に設定方法が違っていたりする場合もあると思いますがUNIX系ならだいたい以下のコマンドで参照できると思います。
$ date 2018年 10月13日 土曜日 11時37分44秒 JST環境変数TZが設定してあれば
/etc/localtime
ではなく前者の方が優先されたりすることもあるようですが、ここではRailsの設定を重点的に見たいのでその辺は割愛します。Rubyの組み込みクラスは上記のようなOSのタイムゾーンを参照しますので、実装する際はこの点は念頭に置いた方がいいでしょう。
例えばTimeクラスの以下のクラスメソッドでは仮にRailsの設定ファイル上、
config.time_zone
が"UTC"であってもOSのタイムゾーンが"JST"の場合は後者の時間で返ってきます。2.5.0 :001 > Time.zone.name => "UTC" 2.5.0 :002 > Time.new => 2018-10-13 13:02:59 +0900 2.5.0 :003 > Time.now => 2018-10-13 13:02:58 +0900 2.5.0 :004 > Time.local(2018, 10, 12) => 2018-10-12 00:00:00 +0900要するにアプリケーションのタイムゾーンとしてconfig.time_zoneで指定したものとOSのタイムゾーンが違っているときに、前者で設定したものを使いたいのに上記を呼び出すと意図した結果にならないので注意です。
ただ、
Time.zone
やTime.current
みたいにActive Supportによって拡張されたものは挙動が違ってきます。2.アプリケーションのタイムゾーン
ここでは上記小見出しは設定ファイルの
config.time_zone
で設定するものを意味します。
これは具体的にはActiveSupport::TimeWithZoneで用いるタイムゾーンを指定する設定項目です。
config.time_zone = 'Asia/Tokyo'
のようにJSTを使うように設定したら、OSのタイムゾーンが仮にUTCなどJST以外のものであってもJSTで時間を返してくれます。2.5.0 :001 > Time.zone.name => "Asia/Tokyo" 2.5.0 :002 > Time.zone.now => Sat, 13 Oct 2018 14:41:44 JST +09:00設定ファイルで指定したタイムゾーンで時間の処理をしたいなら基本的に ActiveSupport::TimeWithZone を使えばOKだと思います。
なお、Time.current
やTime.zone.xxx
、xxx.in_time_zone
等のメソッドを使うと、Time ではなく、TimeWithZone のインスタンスが返されるので注意してください。2.5.0 :005 > Time.zone.now.class => ActiveSupport::TimeWithZone 2.5.0 :006 > Time.current.class => ActiveSupport::TimeWithZone 2.5.0 :007 > Time.zone.now.class => ActiveSupport::TimeWithZone 2.5.0 :011 > Time.now.in_time_zone.class => ActiveSupport::TimeWithZoneこれら
TimeWithZone
のインスタンスを返すものはActiveSupport
によって実装されたものです。
また、3.days.ago
のようなものもActiveSupport
の実装ですから、これらもTimeWithZone
のインスタンスを返します。2.5.0 :009 > 3.days.ago.class => ActiveSupport::TimeWithZoneTimeWithZoneのインスタンスは
new
ではなく、上記で例示したようなもので生成するのが望ましいらしいです(ActiveSupport__TimeWithZoneにその旨記載がある)Time は
Time.utc
のようにUTCで処理できるメソッドがあるので、OSのタイムゾーン以外にUTCも扱えますが、扱えるタイムゾーンはこの2つだけです。
一方 ActiveSupport::TimeWithZone は様々なタイムゾーンを扱えます。2.5.0 :013 > Time.now.in_time_zone('Hawaii') => Fri, 12 Oct 2018 19:55:08 HST -10:00一般的にはタイムゾーンの扱いに長けている ActiveSupport::TimeWithZone を使った方がいいでしょう。
ただし、 ActiveSupport::TimeWithZone はRuby組み込みのメソッドで取得したUTCの時間を基準に、設定されているタイムゾーンの時間に変換するという仕組みらしいのでOSの時間がずれてたら ActiveSupport::TimeWithZone でタイムゾーンを考慮して算出する時刻もずれるので注意が必要です。3. アプリケーションがデータベースをどのタイムゾーンで扱うかの設定
設定ファイルには前章のconfig.time_zone以外にも以下のタイムゾーン設定項目があります。
- config.active_record.default_timezone
- config.active_record.time_zone_aware_attributes
config.active_record.default_timezone
ActiveRecordがマッピングしたDBテーブルのレコードは、created_atやupdated_atのような時刻をプロパティとして保持することになります。
これらはTimeWithZoneのインスタンスです。2.5.0 :010 > Admin.first.created_at.class Admin Load (0.5ms) SELECT `admins`.* FROM `admins` ORDER BY `admins`.`id` ASC LIMIT 1 => ActiveSupport::TimeWithZoneこの設定項目は、上記のようなActiveRecordでActiveSupport::TimeWithZoneを処理する際に基準とするタイムゾーンを指定するものです。
設定できる値は:utc or :localの2択です。
:utcの場合は、ActiveRecordのインスタンスが持っているTimeWithZoneの値をUTCに変換します。OSのタイムゾーンは考慮しません。
:localの場合はOSのタイムゾーンが使われます。設定値は以下で確認できます。
2.5.0 :011 > ActiveRecord::Base.default_timezone => :utcなので、
config.time_zone = 'Asia/Tokyo'
のような設定のアプリでも、config.active_record.default_timezone = :utc
であれば、ActiveRecordでレコード保存する場合に時刻はUTCに変換して保存されます。例えば、日本標準時では15:00の時点で保存するとDB上の記録は0:00となります。
findなどでインスタンス化するときは逆にUTCで保存されたレコードを日本標準時に変換してくれます(ActiveRecordのインスタンスだとcreated_atはActiveSupport::TimeWithZoneのインスタンスなので、config.time_zoneの設定値が適用されるわけです)config.active_record.time_zone_aware_attributes
この項目を明示的にfalseにすると(
config.active_record.time_zone_aware_attributes = false
と記述すると)、ActiveRecordが時刻系のプロパティをActiveSupport::TimeWithZoneではなく、Timeで扱うようになります。2.5.0 :002 > Admin.first.created_at.class Admin Load (0.5ms) SELECT `admins`.* FROM `admins` ORDER BY `admins`.`id` ASC LIMIT 1 => Timeこういう振る舞いにしたいという明確な意図がないなら使うことはないと思います。
ここではこの用途に関してはあまり考えないことにします。個人的に注意した方がいいと思ったこと
- ActiveSupportがTimeクラスを拡張しているのでTimeのメソッド全てがOSのタイムゾーンを参照するTimeのインスタンスを返すとは限らない
config.active_record.default_timezone
は途中で変えちゃいけない(例えばMySQLの場合DATETIME型はタイムゾーン情報も保存しているわけではないのでごちゃごちゃになる)- MySQLの場合は、SQLでNOW()関数を使う場合その時刻はOSのタイムゾーンが基準なので、ActiveRecordによって記録されているタイムゾーンがOSのものと一致してない場合、比較がずれる
- 設定ファイルの既定値はRails自体をバージョンアップした時に変わってしまう可能性があるので明示的に指定した方がいい
おまけ: 実務でやらかした例
2018/10/05 13:00 以降にxxしたいみたいな条件判定で使う時刻をローカルで以下のように出してた。
2.5.0 :012 > Time.new(2018, 10, 5, 13).in_time_zone('Asia/Tokyo') => Fri, 05 Oct 2018 13:00:00 JST +09:00ローカルのMacOSのタイムゾーンはJST。Time.newはOSのタイムゾーン参照する。
一方本番のサーバのOSのタイムゾーンはUTC。だから上記と結果が違う。
2.5.0 :003 > Time.new(2018, 10, 5, 13).in_time_zone('Asia/Tokyo') => Fri, 05 Oct 2018 22:00:00 JST +09:00UTCでの 2018/10/05 13:00 にさらにJSTとの差分を追加しているので9時間分ずれて意図した結果にならなかった。
- 投稿日:2019-10-08T18:27:04+09:00
Railsチュートリアル 第4章<復習>
第4章の復習メモです。
個人的に重要と思ったことを書きます。
調べたことや、知っていたことも含めて書きます。ヘルパー
ビューやコントローラ、モデルから呼び出せるメソッド。
以下の二種類がある。
- 組み込みヘルパー
- 新しく定義できるカスタムヘルパー
1は、Railsで元々用意されている。
2は、自分で定義でき、以下のファイルに記述する。
app/helpers/application_helper.rb※以下のサイトも参考にさせていただきました
https://www.sejuku.net/blog/28563文字列の表現
文字列は、シングルクォート(')またはダブルクォート(")で囲む。
前者は、囲った物をそのまま表現する。
よって、正規表現(\n等)や、式展開(文字列中に変数を埋め込む)は無効となる。
後者は、両方とも有効。引数、カッコの省略
メソッドにデフォルト引数を設定している場合、引数、カッコを省略できる。
# メソッドの定義 def string_message(str = '') # デフォルト引数として''を設定 . . end # 呼び出す側 string_message最後の引数がハッシュの場合、波カッコを省略できる。
# 以下の二つは同じ意味となる stylesheet_link_tag 'application', { media: 'all', 'data-turbolinks-track': 'reload' } stylesheet_link_tag 'application', media: 'all', 'data-turbolinks-track': 'reload'範囲 (range) オブジェクト
1..10
、a..z
のように表現する。
to_aメソッドで配列に変換すると、範囲内の値が全て、配列に格納される。ブロック
{}で囲むパターンと、do~endで囲むパターンがある。
すいません、文章にできるほど理解できていないので、
リンクを貼らせていただきます・・・
https://www.sejuku.net/blog/14291inspectメソッド
対象のリテラル(プログラムに記述するデータ値。コードに書いた値。)を返却する。
>> puts (1..5).to_a # 配列を文字列として出力 1 2 3 4 5 >> puts (1..5).to_a.inspect # 配列のリテラルを出力 [1, 2, 3, 4, 5] >> puts :name, :name.inspect name :name >> puts "It worked!", "It worked!".inspect It worked! "It worked!"以下を参考にさせていただきました
https://www.sejuku.net/blog/77039
http://www.designmap.info/2016/12/16/javascript-3/#i-2クラス、継承
- 投稿日:2019-10-08T18:26:52+09:00
Railsチュートリアル 第3章<復習>
第3章の復習メモです。
個人的に重要と思ったことを書きます。
調べたことや、知っていたことも含めて書きます。Webページの作成
Railsで、Webページ作成に最低必要なのは、以下の3つ。
- URLのルーティング
- 1に対応するコントローラ及び、アクションの作成
- 2に対応するビューの作成
以下のコマンドを実行すると、上記3つを自動生成してくれる。
$ rails generate controller <コントローラ名> <アクション名1> <アクション名2> <アクション名xx>
- ルーティングについて
- config/routes.rbファイルにルーティングが追記される。
- コントローラについて
- 慣習的に、コントローラ名はキャメルケース(頭だけ大文字)で記載する。
- 生成されるコントローラは、スネークケース(単語間を_でつないだ形)になる。
- アクション名は全て小文字にする。また、いくつ書いても良い。
- ビューについて
- コントローラのアクション毎、ビューが生成される。
切り戻しについて
コマンドを打ち間違えて、変なファイルを作ってしまった場合、
元の状態に戻すためのコマンドが用意されている。
- コントローラを戻す
$ rails destroy controller <モデル名> <アクション名1> <アクション名2>
- モデルを戻す
$ rails destroy model <モデル名>
- DBへの反映を1つ戻す
$ rails db:rollback
- DBへの反映を全部戻す
$ rails db:migrate VERSION=0テストについて
$ rails testで、テストを実行できる。
テストコードは、あらかじめ生成されている物もある。
また、Guardを使ってテストを自動化できるみたい。
詳しく理解するのはまたの機会に。Gitについて
git push origin <ブランチ名>で、GitHub上のブランチにPUSHされる。
GitHubにブランチが存在しない場合、新規作成される。最低限、3章まではやろうと思っていたので、目標は達成しました。
4章以降についても、できれば続けていきたいと思います。
- 投稿日:2019-10-08T15:40:07+09:00
Ruby on Rails アプリ作成のはじめのはじめ
Ruby on Rails作成におけるアウトプット用も兼ねて記載していきます。
間違い等あればご連絡ください。新規Railsアプリケーションの作成
アプリケーションを配置するディレクトリを作る。
自分の作成したい場所までターミナルで移動する。
cd
現在のディレクトリ(カレントディレクトリ)を移動する
mkdir
新しくディレクトリを作成する
pwd
現在のディレクトリ(カレントディレクトリ)のパスを表示する
ls
現在のディレクトリ(カレントディレクトリ)のファイル一覧を表示する新規アプリケーションを作成
ターミナルで「rails new」コマンドの実行
rails new アプリケーション名 -オプション名これでRuby on Railsのアプリ制作における雛形ができるので、ここから色々と編集していくことで立派なアプリへと成長させていくことが可能となる。
- 投稿日:2019-10-08T14:52:21+09:00
[Rails] Slackにエラー通知を行う
メモ
graphql_controllerの処理の流れ
エンドポイントをAPIモードのgraphql_controllerのexecuteメソッドに指定しているので、まずここが呼び出される。
(1) Webhook URLの取得
下記から、URLを取得する。
https://slack.com/services/new/incoming-webhook
(2) credentials.yml に秘匿情報を記載
- webhook_url
- channel
は隠していた方が良いと思うので、credentials.ymlに記載する
$ EDITOR="vi" bin/rails credentials:editcredentials.ymlslack: webhook_url: https://hooks.slack.com/services/... error_channel: #{YOUR_CHANNEL} notification_channel: #{YOUR_CHANNEL}(3) graphql_controllerに設定
graphql_controller.rbclass GraphqlController < ActionController::API def execute 処理... rescue => e slack_error_notifier(e, query, request, current_user) end private # https://api.slack.com/docs/message-attachments def slack_error_notifier(e, query, request, current_user) notifier = Slack::Notifier.new Rails.application.credentials.slack[:webhook_url].to_s, username: "#{YOUR_USERNAME}" attachments = { author_name: Rails.env.to_s, text: "■ *Request*\n" << "*#{request.headers[:REQUEST_METHOD]}* #{request.headers[:REQUEST_URI]}" \ "\n\n■ *Time*\n" << "#{Time.zone.now}" \ "\n\n■ *Current User*\n" << "*USER_ID* #{current_user&.id || "NONE"}" \ "\n\n■ *User Agent*\n" << "#{request.headers[:HTTP_USER_AGENT]}" \ "\n\n■ *IP*\n" << "#{request.headers[:REMOTE_ADDR]}" \ "\n\n■ *Query*\n" << "#{query}" \ "\n\n■ *Message*\n" << "#{e.message}" \ "\n\n■ *Backtrace*\n" << e.backtrace.join("\n").to_s, color: "danger", } notifier.post attachments: [attachments], channel: "#{YOUR_CHANNEL}" end end(4) 通知の確認
- requestの中身を全て確認する。
text: "■ *Request*\n" + "#{request.headers.sort.map { |k, v| "#{k}:#{v}" }}" + "\n\n■ *User Agent*\n" + "#{request.headers[:HTTP_USER_AGENT]}" + "\n\n■ *IP*\n" + "Im P!!" + "\n\n■ *Query*\n" + "#{query}" + "\n\n■ *Message*\n" + "#{e.message}" + "\n\n■ *Backtrace*\n" + "#{e.backtrace.join("\n")}",参考
Railsヘッダーの中身について
エラーについて
- Rails のエラー処理について知ってる範囲でまとめ
- 【Rails】例外処理の書き方(begin, rescue, raise,retry, ensure)
- Rails の rescue_from で拾えない例外を exceptions_app で処理する
Slackの通知カスタマイズ
Action Controllerについて
Action Dispatchについて
- 投稿日:2019-10-08T14:52:04+09:00
VScodeでRailsをデバッグする
経緯
- VScodeでRailsアプリケーションをdebugしたくなった
- 便利だから(たぶん)
- ちなみに僕のVScodeは日本語になっているのでよしなに解釈してください
設定
プラグインのインストール
gemのインストール
- 次は必要になるgemをインストールします
$ gem install ruby-debug-ide $ gem install debase構成の追加
- ポチッと
構成の追加
をクリックします
- Rubyを選択(あるはず)
launch.json
が作成されるはずなので中身をこんな感じにしますvscode/launch.json{ "version": "0.2.0", "configurations": [ { "name": "Debug Rails", "type": "Ruby", "request": "launch", "cwd": "${workspaceRoot}", "program": "${workspaceRoot}/bin/rails", "pathToRDebugIDE": "/home/trantan/.rbenv/versions/2.5.1/bin/rdebug-ide", "args": [ "server" ] } ] }実行
- あとは実行するだけです
- 左側のサイドバーに
Debug Rails
があると思うのでそれをポチっとしましょう
- そうすると、Railsサーバーが立ち上がりデバッグコンソールにババーッと何かが表示されると思います
ブレークポイントを貼る
- もちろん実行するだけでは分からないのでブレークポイントを貼って処理を止めます
- ババーッと処理している何かしらのファイルに貼りましょう
- コントローラー辺りにしますか
- 数字の左脇辺りをポチッと押すとそこで処理が止まってくれます
あとはサイドバーをみる
- どんな値を持っているかとかスタックがどうなっているのかが左サイドバーに出ます(設定がデフォルトなら)
- どこにブレークポイントを貼ったのかも分かります
- 他にも何かあると思いますが割愛しますm(_ _)m
結論
- 意外と簡単に設定できるのでぜひデバッグをやってみてください
- 便利!!!!
参考
- 投稿日:2019-10-08T11:38:06+09:00
Rails6 のちょい足しな新機能を試す91(ActiveRecord annotate編)
はじめに
Rails 6 に追加された新機能を試す第91段。 今回は、
ActiveRecord annotate
編です。
Rails 6 では、 ActiveRecord で、発行される SQL にコメントを含めることができるようにannotate
メソッドが追加されました。
ログに出力して解析したり、デバッグしたりするときに便利そうです。Ruby 2.6.4, Rails 6.0.0 で確認しました。
$ rails --version Rails 6.0.0今回は、User の CRUD を作り、一覧ページを表示するとき、そこで実行される SQL がどのコントローラのどのアクションから呼ばれているのかわかるようにしてみます。
プロジェクトを作る
rails new rails_sandbox cd rails_sandbox
User の CRUD を作る
name をもつ User の CRUD を作ります
bin/rails g scaffold User nameコントローラとアクションの名前を返すメソッドを定義する
full_action_name
というプライベートメソッドをApplicationController
に追加しますapp/controllers/application_controller.rbclass ApplicationController < ActionController::Base private def full_action_name "#{self.class.name}##{action_name}" end endApplicationRecord に scope を追加する
annotate
を使った scope を1つApplicationRecord
に追加します。app/models/application_record.rbclass ApplicationRecord < ActiveRecord::Base self.abstract_class = true scope :called_from, ->(from) { annotate("called from #{from}") } endUserController#index を変更する
User.all
がUsersController#index
から呼ばれていることがわかるように、修正します。app/controllers/users_controller.rbclass UsersController < ApplicationController ... def index @users = User.all.called_from(full_action_name) end ... end実際に一覧ページを表示してコンソールを確認する
rails server
を実行し、ブラウザから http://localhost:3000/users にアクセスし、コンソールを確認します。
SQL 文にコメント"called from UsersController#index" が含まれていることがわかります。... User Load (0.4ms) SELECT "users".* FROM "users" /* called from UsersController#index */ ...試したソース
試したソースは以下にあります。
https://github.com/suketa/rails_sandbox/tree/try091_activerecord_annotate参考情報
- 投稿日:2019-10-08T09:38:45+09:00
capybaraとselenium-webdriverとは
capybaraとselenium-webdriverとは
capybara
統合テスト(Feature Spec/フィーチャースペック)を書くときに、ブラウザにを仮想的に操作するためのgem。
細かい動作まで検証できる。selenium-webdriver
capybaraはシンプルなブラウザシミュレータ(つまりドライバ)を使って、 テストに書かれたタスクを実行していきます。このドライバは Rack::Test というドライバで、速くて信頼性が高いのですが、JavaScript の実行はサポートしていません。
javascriptをテストするためにselenium-webdriverというgemをを使います。CapybaraでもデフォルトのJavaScript ドライバになっていて、
デフォルトでは Capybara は selenium-webdriver に対して Firefox を使ってテストを実行するように伝えます。ですのでChromeを使いたい場合はそのように設定しなければなりません。
- 投稿日:2019-10-08T08:25:23+09:00
【個人開発】プログラミングを勉強したので誰かの書き込みを表示するだけのWebサイトを作った
kotoniwa
何をするwebサイトなのか
ユーザーそれぞれが好きな言葉を書き込む、そして画面をクリックすると誰かが書いた言葉がランダムでぼんやりと出てくるだけのサイト。
使ったもの
ruby
rails
javascript
jquery
Nginx
unicorn
postgresql自分のスキル
専門学校でサーバーとネットワークの勉強をしていたけど、プログラミングの経験はほぼ0(シェルスクリプトちょっとやったかなくらい)。
他人が書いたrailsアプリを自分が立てたapacheサーバーで公開した事はある。
railsもjavascriptもコードを見たことはあります程度。
自分で1からコードを書いてというのはこれが初めて。
勉強したこと
udemyでjavascriptとrailsとhtmlとcssの講座を購入してみたけど最初にざっと見ただけであまり活用しなかった。結局これ実際にやってみないとよくわからないな、と思ったので。
実装したいと思ったことをその都度ググって、よくわからなかったらそこを深掘りして、みたいな感じで作りながら学習を進めた。
作るまでの流れ
現在はサーバー運用系のお仕事をしていて、web系の方に転職してみようかなという思いが出てきたのでとりあえず何かを作ってみることに。
今まで自分で一からwebサイトを作ったことはなかったのであんまり難しいことをやろうとすると挫折するだろうと思い、とにかくシンプルなものを作りたかった。
wikipediaをランダムで表示したりするやつとかのランダム系のサイトが好きだったのでそんな感じのをイメージしていて、「なんでも好きに書いていい」となった時に皆がどんなことを書くのかに興味があったのでこれを作ろうと思った。
感想
とりあえず公開まで持っていけてよかった。
こんな簡単な感じのサイトでもここまで躓きポイントが大量にあるのか…と思ったので、作ろうと思っても途中で諦めてしまう人は大量にいると思う。
次はもうちょい真面目なwebサービス感のあるサイトを作る予定。
もっと技術つけてはやく転職したい。
- 投稿日:2019-10-08T06:49:04+09:00
Rails on Railsにおける命名規則
- 投稿日:2019-10-08T05:21:40+09:00
Vagrant + RailsでHerokuにHello ,World!する
vagrantローカル環境でhello world!を表示するアプリを作成しherokuにデプロイするまでの忘備録
環境
Ruby 2.4.0
Ruby on Rails 5.1.7
rbenv 1.1.2-2-g4e92322
Node.js v4.9.1
bundler 2.0.2
Vagrantローカル環境構築
https://qiita.com/karlley/items/0812bd33a3952ea40de5
上記URLを参考に環境構築
上記URLではRails 5.1.6で進めていますが今回は5.1.7を使用
順番に進めれば
/home/vagrant/centos67/your_workspace/your_app
にアプリが作成され「Yay! Your on Rails!」まで表示できるはずですまずはローカル環境でHello World!
作成されたアプリのファイルを編集し「Hello World!」が表示されるようにします
修正する使用するファイルは2つ
app/controllers/application_controller.rb
config/route.rb
上記のファイルを以下のように修正
app/controllers/application_controller.rbclass ApplicationController < ActionController::Base protect_from_forgery with: :exception def hello render html: "Hello, World!" end endconfig/route.rbRails.application.routes.draw do root 'application#hello' end
http://192.168.33.10:3000
で「Hello World!」が表示されているか確認Git
- 初期設定
- Initial commit
1. 初期設定
HerokuのデプロイにはGitを使用するので初期設定
設定を確認
$ git config --list core.repositoryformatversion=0 core.filemode=true core.bare=false core.logallrefupdates=true core.ignorecase=trueusernameとemailが未設定の場合は下記コマンドで設定
$ git config --global user.name "Your Name" $ git config --global user.email your.email@example.com $ git congit --list user.name=Your Name user.email=your.email@example.com core.repositoryformatversion=0 core.filemode=true core.bare=false core.logallrefupdates=true core.ignorecase=true設定を反映し、初期化
$ git init Reinitialized existing Git repository in /home/vagrant/centos67/workspace/hello_app/.git/上記コマンドを実行するとアプリのルートディレクトリに
.git
が作成されます2. Initial commit
Git設定後、最初のコミットを作成
ファイルをリポジトリに追加、確認
$ git add -A $ git status # On branch master # # Initial commit . .リポジトリにコミット、確認
$ git commit -m "initialize repository" 56 files changed, 1181 insertions(+), 0 deletions(-) create mode 100644 .gitignore . .$ git log commit 28b... Author: Your Name <your.email@example.com> . .最初のコミットが作成されました
データベース
- postgreSQL
- sqlite3
- 設定したGemをインストール
1. postgreSQL
Herokuで使用するデータベースはデフォルトでpostgreSQLなのでGemの設定
Railsの開発環境でのデフォルトはsqlite3
Gemfileに下記を追記
Gemfilegroup :production do gem 'pg', '0.20.0' end
:production do
は本番環境のみで使用するという意味2. sqlite3
既存のsqlite3の記述をコメントアウト、または削除
Gemfile#gem 'sqlite3'開発/テスト環境のみの仕様に変更する為、
group :development, :test do
にgem 'sqlite3'
を追加Gemfilegroup :development, :test do # sqlite3 for development/test only ← 追記 gem 'sqlite3' ← 追記 # Call 'byebug' anywhere in the code to stop execution and get a debugger console gem 'byebug', platforms: [:mri, :mingw, :x64_mingw] # Adds support for Capybara system testing and selenium driver gem 'capybara', '>= 2.15' gem 'selenium-webdriver' end3. 設定したGemをインストール
$ bundle install --without production
--without producton
をオプションで付ける事で本番環境へのデプロイの失敗を防止pg gemを追加したことやRubyバージョンを指定したことをGemfile.lockに反映させないと、本番環境へのデプロイで失敗してしまうためです。
引用:RailsTutorilal
Gemfileを変更したので再度コミット
$ git commit -a -m "Update Gemfile for Heroku"
-a
オプションは変更のあったすべてのファイルという意味Heroku
- Herokuとは
- Heroku CLI インストール
- ssh鍵を追加
- デプロイ
1. Herokuとは
webアプリ用ホスティングサービス
Gitを使う事で簡単に本番環境にデプロイできる
Heroku本番環境ではデータベースにpostgreSQLを使用(Railsの開発環境でのデフォルトはsqlite3)
2. Heroku CLI インストール
Herokuをコマンドラインで使用するために必要
下記URLを参考にしてください
https://qiita.com/karlley/items/c423d02eee2292dab1f9
3. Heroku SSH鍵追加
/home/vagrant/.ssh
にSSH鍵があるか確認$ cd ~/.ssh $ ls -a authorized_keys
id_rsa
,id_rsa.pub
が無い場合はSSH鍵が無いので下記URLを参考に生成https://git-scm.com/book/ja/v1/Git-サーバー-SSH-公開鍵の作成
$ cd ~/.ssh $ ssh-keygen $ ls -a authorized_keys id_rsa id_rsa.pubSSH鍵が生成されたのでHerokuにログインし鍵を追加
Herokuアカウントが無い場合は下記URLから作成
HerokuアカウントのEmail,Passwordを入力しログイン
$ heroku login --interactive heroku: Enter your login credentials Email: Password:Herokuにログイン後、SSH鍵を追加
$ heroku keys:add Found an SSH public key at /home/vagrant/.ssh/id_rsa.pub ? Would you like to upload it to Heroku? Uploading /home/vagrant/.ssh/id_rsa.pub SSH key... doneHerokuにSSH鍵が追加されました
HerokuのアカウントページのSSH Keysで追加された鍵を確認できます4. デプロイ
Herokuにアプリケーションを作成
$ heroku create your-app-name Creating app... done, ⬢ your-app-name . .アプリ名が表示されアプリケーションが作成されます
リポジトリをプッシュ
$ git push heroku master . . remote: Verifying deploy... done. . . * [new branch] master -> masterデプロイ成功したのでブラウザで確認
$ heroku open . . ▸ Manually visit https://your-app-url/ in your browser.表示されたURLをブラウザで確認
無事「Hello world!」できました!
あっさり進んでいるように見えますが私のようなプログラミング初心者にとってローカル環境からデプロイするのは一つの大きな壁でした汗
同じように悩んでいる方に少しでも参考になればと思います!
- 投稿日:2019-10-08T00:18:57+09:00
自分用メモ(form_for関連・render・パスの確認)
render (Viewでの役割)
→部分テンプレートをビューに出力する
ex)<%= render 'form'%> ←ここに _form.html.erbが挿入される
post:@postって何
postという名のパラメーターにテンプレート変数@postを渡しなさい
ex) <%= render 'form' post:@post%>
→部分テンプレートの_form.html.erbの post という変数に @postを渡せ・オプション色々はここに書いてある
https://web-camp.io/magazine/archives/17675form_for(ビューヘルパーの一種)
→特定のモデルを編集するためのフォーム
(ビューヘルパーにはモデルのプロパティ名に対応した名前(シンボル)を渡すという点を覚えておくと良いらしい)あまりわからないのであとでビューヘルパーについて学ぶ
モデルを受け取る ex)post
↓
form_for(model) do |f|
ーーーbodyーーー
endbodyの中身
<% f.text_field :title %>
→postオブジェクトを編集するフォームで、titleプロパティに対応するテキストボックスf.text_field
f.submit
→新規作成と編集の時では挙動が異なる
新規作成の時→create
編集する時→updatenewで@postに代入する意味
formから代入する情報を格納するための器を作るため
newからcreateまでの流れ
フォーム作っておく
→データ受け取るときに受け取るデータ絞れる(1)(C-new)newで空の容器@postを作成
↓
(V)render 'なんたら',post: @post
でformのpostというパラメータに@postを渡す
↓
(V)データ入力
↓
(V)submitでデータ送信
↓
(C-create)@postにデータを受け取る(再構築)
・データを絞って受け取る params.require(:model名).permit(:A,:B,:C...)
(Strongパラメータっていうらしい)
↓
保存パスの確認
rake routes
で出てくる
- 投稿日:2019-10-08T00:14:52+09:00
attr_encryptedなカラムを検索する方法
初めまして、ガッシーです。Qiita初投稿となります。(なんか癖でQuiitaって打っちゃうんですよね)
日頃Railsの開発で躓いて調べたことなどを書き留めていければなと思ってます。
そんなところで本題へ。railsでカラムを暗号化する際には一般的にattr_encryptedを利用するかと思いますが
READMEを翻訳しますと暗号化されたデータを検索することはできません。検索できないため、インデックスを作成することもできません。
との記載があります。
でも暗号化しつつ検索したいことって結構あると思うんですよね。そこで登場するGemがblind_indexです。
ただし LIKE検索はできない ので注意してください。blind_indexとは
例えばnameというカラムでattr_encryptedを使うときは
encrypted_name
とencrypted_name_iv
の2つのカラムを用意すると思いますが、
それに加えてencrypted_name_bidx
というカラムを追加してあげることで、そこに検索できる値を保存する感じです。早速やってみましょう。設定
READMEに書いてあることをそのままやっていけばいいのですが一応書きます。
Gemfileに下記を追加してbundle install
gem 'blind_index'コンソールを起動して下記コードを実行しランダムなキーを取得します。
irb(main):001:0> BlindIndex.generate_key # SecureRandom.hex(32).force_encoding(Encoding::US_ASCII) でも同じ => "222189cbba7ba0381c66faf8f687197b4bd4256a99bf81c917256c2871ca5289"キーを保存・設定します。
credentials.yml.encblind_index_master_key: "222189cbba7ba0381c66faf8f687197b4bd4256a99bf81c917256c2871ca5289"config/initializers/blind_index.rbBlindIndex.master_key = Rails.application.credentials.blind_index_master_key(initializerを読み込むためサーバーは再起動しておいてください)
blind_index用のカラムを追加します。
db/migrate/add_name_bidx_to_users.rbadd_column :users, :encrypted_name_bidx, :stringmodelも変更を加えます。
app/models/user.rbclass User < ApplicationRecord attr_encrypted :name, key: Rails.application.credentials.encrypted_key blind_index :name_bidx, key: Rails.application.credentials.blind_index_master_key #←こちら追加 end以上で設定は完了です!
※既に暗号化カラムが保存されている方はコンソールにて下記コマンドを実行することで既存のレコードにも対応できます。
User.unscoped.where(encrypted_name_bidx: nil).find_each do |user| user.compute_name_bidx user.save(validate: false) end実行
User.where(name: "山田太郎")これができるようになっているはずです。
感想
完全一致検索しかできないけど何もできないよりはマシか・・・
知識がないのですが、最初こちらの記事 attr_encryptedされたカラムに対してwhere likeしたかった。を見ましたが恐らく現在ivカラムを利用した暗号化を行っている場合は適応できないかな?と思ってます。
Qiita初めての記事となりましたのでもし誤りがありましたらご指摘いただければ幸いです。