196の日記

セキュリティ系の勉強、その他開発メモとか雑談、忘れそうな計算式などを書き溜める場所になっています. githhubはUnity触っていた頃ものがメイン https://github.com/196kakinuma [twitter https://twitter.com/196Ikuchil]

ruby チュートリアル 14章メモ

ActiveRecord through

n:mの関係を表すのに使用。1:nの関係はhas_manybelongs_toで表した。また後者の繋ぎ方であると、直接的な結びつきになるのに対して、throughを使用する場合は、2モデル間にクッションとなるモデルを定義してそこに関係をしまっていくイメージ。チュートリアルではユーザ間のフォローに使用して、誰が誰をフォローしているかを表すために使用。
f:id:thinline196:20181205135325p:plain
f:id:thinline196:20181205135432p:plain

userに追加する

userモデルと新たに作成したrelationshipモデルに関係性を追記する。

# app/models/user.rb
class User < ApplicationRecord
  has_many :microposts, dependent: :destroy # micropostは外部キーがuser_idであったためこれでok
  has_many :active_relationships, class_name:  "Relationship", #外部キーはfollower_idとして定義しなければならない(followerというクラスは存在しない)
                                  foreign_key: "follower_id",
                                  dependent:   :destroy
  ...
end


# app/models/relationship.rb
class Relationship < ApplicationRecord
  belongs_to :follower, class_name: "User"
  belongs_to :followed, class_name: "User"
end


定義されるメソッド

active_relationship.follower フォロワーを返します active_relationship.followed フォローしているユーザーを返します user.active_relationships.create(followed_id: other_user.id) userと紐付けて能動的関係を作成/登録する user.active_relationships.create!(followed_id: other_user.id) userを紐付けて能動的関係を作成/登録する (失敗時にエラーを出力) user.active_relationships.build(followed_id: other_user.id) userと紐付けた新しいRelationshipオブジェクトを返す

非同期通信

form_withを使用して非同期通信を行う場合、remote:trueを指定してあげることで非同期通信となる。一つ注意としては、form_withではデフォルトでremote:trueが設定されている。(前身のform_forではデフォルトではなく明示的に指定が必要であった) なので、非同期にしたくない場合にlocal:trueを指定してあげることを忘れないようにする。

Unobtrusive Javascript

RailsではJSを前面に出さないようにする習わしがあるらしい。 http://railscasts.com/episodes/205-unobtrusive-javascript

respond_to

コントローラ内で使用した。リクエストで指定されたフォーマットでレスポンスを返すためのメソッド。

    respond_to do |format|
      format.html { redirect_to @user }
      format.js
    end

例えばこれがcreateメソッド内で呼ばれているのであれば、views/対応するモデル複数名/create.js.erbJSでのレスポンスの際に呼ばれるファイルとなる。

にしてもこの記事は酷いと思う。 => https://techacademy.jp/magazine/17744

Ajaxのテスト(RSpec)

RSpecajaxフォームのテストを行うにはxhrを追記してあげる。具体的には下。

    xhr :get ~~~

model間のRailsの予測

# models/user.rb
has_many :followeds, through: :active_relationships

上の1行をみて、railsactive_relationshipsfollowed_idを使って対象ユーザを取得しようとする(複数形を単数形にする). 自分でカラムを指定する場合、自分で名前を指定したい場合は下のように書く。

has_many :following, through: :active_relationships, source: :followed

followed+_idカラムを対象とし、userモデル内で呼び出すときはfollowingという名前で呼び出すことが可能。

個人的なメモ

# /models/user.rb
  has_many :active_relationships, class_name: "Relationship",
                                  foreign_key: "follower_id",
                                  dependent: :destroy
  has_many :following, through: :active_relationships, source: :followed

上のコードがuserモデルに書いてあることで、follower_idfollowed_idのカラム(どちらもUserモデルにbelongs_to)をもつRelationshipモデルから、user.followingで、relationshipのfollowedにあるid(userがフォローしているアカウント)が配列で取得できる。鍵になっているのが上の定義で、active_relationshipsを呼ぶことで、関連付いている自分のidfollower_idを頼りに、関係あるデータだけを取得してきている。よって、下のfollowingの定義では実質”関係あるデータの中から”のみデータを探索することができている。(下の定義だけ見てては、どうやって自分に関係あるレコードを抽出している理解できず、困惑していた)

memberとcollection

config/route内でresourcesを使用してルーティングを設定するとき、collectionメソッドを使用すると、resourcesで設定したルーティングにつけ加わる感じで、新たなアクション&ルーティングを定義できる。

resources :users do
  collection do
    get :tigers
  end
end


memberメソッドを使用すると特定のデータに対するアクションを生成することが可能になる。チュートリアルでは、ユーザのフォロー/フォロワーを表示するために使用。(~/users/1/following)

  resources :users do
    member do
      get :following, :followers
    end
  end


map

rubyのmapメソッドは、列挙可能なオブジェクトを配列に変換してくれる。

[3] pry(main)> [1,2,3,4].map{|i| i.to_s}
=> ["1", "2", "3", "4"]

[4] pry(main)> [1,2,3,4].map(&:to_s) #省略系
=> ["1", "2", "3", "4"]

[7] pry(main)> [1,2,3,4].map(&:to_s).join(",")
=> "1,2,3,4"
[8] pry(main)>

チュートリアルではユーザがフォローしている人のidを取得するの使用

>> User.first.following.map(&:id)
=> [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
42, 43, 44, 45, 46, 47, 48, 49, 50, 51]

ActiveRecordでは、下のようなメソッドも用意されていて全く同じ動きをする。これはhas_many :followingの関連付けを行った時に自動で生成され、+_idsをつける形で実装される。

>> User.first.following_ids
=> [3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22,
23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41,
42, 43, 44, 45, 46, 47, 48, 49, 50, 51]

サブクエリ

SELECT文のなかにSELECT文を記述する(括弧でくくる)。一般的に可読性はよくなる。チュートリアルでは効率をあげるためとの表記があった。これは、既存実装のfollowing_idsを使用した場合、DBへのアクセスが二回発生するからとのこと。サブクエリとして自分で実装することで、DB内でちょちょいとやってくれるらしい。

ruby チュートリアル 13章 メモ

belongs_to

指定したモデルと1対1の関係を持つ。参照元テーブルから参照先テーブルにアクセスする。モデル生成時にuser:referencesをつけるとモデル内に自動生成される。

#app/models/micropost.rb
class Micropost < ApplicationRecord
   belongs_to :user
end

user:references

上の通りコマンドでモデル生成時にuser:referencesをつけると、自動的にインデックスと外部参照キー付きのuser_idカラムが追加される。

  def change
    create_table :microposts do |t|
      t.references :user, foreign_key: true #ここ
      t.timestamps
    end
  end

複合キーインデックス (Multiple Key Index)

複数の条件で並び替えができるようにする。下の時は、user_idに関連付けられたすべてのマイクロポストを作成時刻の逆順で取り出しやすくなる。注意としては、2つ目以降にしてしたカラムのみでインデックスは使用できない。あくまでuser_idでのソート後にcreated_atでソートが可能。

    add_index :microposts, [:user_id, :created_at]


モデルのvalid?メソッド

モデル内でのvalidatesで弾かれてる値が入っている場合にfalseが返される。正確に言うと、valid?メソッドを使用した際に初めて保持されている値が評価され、booleanを返す。errors.messagesインスタンスメソッドを使用すると、発生したエラーにアクセスできる。

 test "content should be present" do
    @micropost.content = "   "
    assert_not @micropost.valid?
  end


デフォルトスコープ

dbから引っ張り出す際の条件(orderやwhere)をデフォルトで指定できる。が、ググると否定的な記事が多かった。ある時特別な条件で引っ張ってきたい時に、スコープを外すのが大変&見落としがちになるからだそう。チュートリアルではmicropostを新しい順に取得するために使用していた。

Dependent: destroy

下のように使用すると、Userを削除した際にUesrに紐づいていたMicropostも同時に削除される。こうすることで、db内にアクセス不可能なMicropostが残ってしまうのを防ぐことができる。

takeメソッド

チュートリアルでUserモデルから最初の6人を取得するために使用した。1~10のArrayから最初の6つをとるコードは下。

[5] pry(main)> (1..10).to_a.take(6)
=> [1, 2, 3, 4, 5, 6]


uninitialized constant ~Controller

この章に直接関係しないですが、RSpecでテスト書いている際に下のようなエラーが出ました。出現箇所としては、Controllerのテストで、createや`destroy``アクションを読んだ時でした。

ActionController::RoutingError:
        uninitialized constant MicropostController


根本原因としては、config/route.rbのルーティングミス。

#間違い
resources :micropost,           only:[:create,:destroy]
#正しい
resources :microposts,           only:[:create,:destroy]


単数形のままだと、確かにcreateのパス取得にmicropost_index_pathとか言う謎文字列を使わされました。正しく設定ができていれば、createアクションはmicroposts_pathで取得することができます。

current_userヘルパー

app/controllers/microposts_controller.rbで以前作成したcurrent_userヘルパーが再び使用されるが、これは定義元のSessionsHelperが大元のApplicationControllerincludeされているため、どこでも使える。
注意として、決してユーザ情報が保持されたインスタンス変数がコントローラ間で共有されているわけではなく、ヘルパーを介してセッションとクッキーを調べ、その情報を利用してユーザ情報についてコントロールしている。なので、共有しているように見えているのは、ヘルパーの実装がそうやって扱えるようにされているから。

SQLクエリのエスケープ

?記号で実現する。具体的には下参照。しかし、ググってみてもあまりこのやり方はヒットしないので、今後チュートリアルで別のやり方が登場するかも..?

 Micropost.where("user_id = ?", id)


request.referrer

リクエストが発行されたページのURLを返してくれる。フレンドフォワーディングではrequest.urlを使用して飛ぼうとしていた先のURLを拾っていた。注意として、nilを返してくる場合もあるので、||でデフォルトのジャンプ先を指定してあげておくと良い。

redirect_to request.referrer || root_url


Rails5の新機能としてredirect_back(fallback_location: root_url)と書くと上のコードと同じ動きをしてくれる。

テストでwill_paginateが表示されない

この賞に限ったことではないが、テストでdiv.paginationに一致する部分を探しても見つからないことがあった。ブラウザ上では確認済みだったので原因探しに困った。結果として、ページネートするコンテンツが1つしか生成されていなかったのが原因。テスト時のページ表示前にダミーデータをたくさん作ってあげることで解決する。(1ページのデフォルト値よりも多く)

CarrierWave

画像アップローダのgem

Mini_Magick

画像のリサイズができるようになるGem. ただ、ImageMagickを使用することになるので、脆弱性とか心配? MiniMagick自身の役割としては、本体にインストールしたImageMagickRubyの橋渡しになってくれるGem ImageMagickは様々な画像に対応できているがゆえにガバガバになっているイメージがあるので、載せられる画像のフォーマットを制限する。チュートリアルではCarrierWaveを利用している。

MIMEタイプ

データのタイプを指定したりする。元々は、テキストしか扱えない電子メールで様々なフォーマットのデータを扱えるようにするために使用されている。チュートリアルでは画像の拡張子をクライアント側で限定するために使用。

git rebaseのお勉強

読んだもの

このページは図解もわかりやすいし、状況も似ていたので、ありがたかった。しかし、最後のrebase -iでコミットをまとめてしまうのは、後で見返す際に良い影響があるとは思えないので微妙だと感じた。
git rebaseを初めて使った際のまとめ - Qiita

ちょっとわかりにくいけど、便利さは伝わってきた。公開リポジトリrebaseご法度なのを理解できた。rebaseを行うのはローカルの自分しか触っていない部分のみに絞る。 Git - リベース

状況

あまり理想的な状況ではなかったけれど、masterから派生したb1ブランチがあり、b1のプルリクを投げてレビュー待ちの間(ここでかなり待たされる状況)、b1の最終コミットからb2ブランチを伸ばし、作業を進めた。最終的にどちらのチェックも通った時、この二つをどうマージして行こうかといった状況。せっかくなのでrebase使う勉強をしようかなと。
f:id:thinline196:20181205010244p:plain

結果

  1. b1masterに普通にマージ
  2. b2の派生元をmasterに変更(git rebase master (#b2ブランチ上で実行)) (コンフリクトの可能性あり& ここで解消) $ git fetch origin $ git reset --hard origin/master(masterを最新の先頭にする(ここはb2の派生元をmasterの最新にしたかったのでこの処理)) $ git checkout b2 $ git rebase master
  3. b2をリモートにプッシュ $ git push -f origin b2`
  4. b2masterにマージ or 作業続行

    今更

    今更こんなこと勉強しているの恥ずかしいです。以降使えるようになります。。。

【ネタバレあり】Mr.Children 重力と呼吸ツアー 横浜アリーナ2日目

2018/11/29(木)

待ちに待ちくたびれたライブでした。1つのツアーを何公演も見るような人間ではないので、今回もめちゃ楽しみにしてました!そんなライブの感想を未来の自分のために(ホント自由勝手に)書いていくので、興味のない人、それからネタバレが気になる人は絶対見ないでください。
































じゃ1曲目から書きますよ。 (誤字とか気にせずに、特に曲名のタイポとか)

SINGLES

実は公演の途中まで”SINGLES”は今回演奏しないのかな?とか思ってました。思いっきり最初にやっていたのをライブ中うっすらと思い出し、帰ってセトリ確認したらやっぱりって感じです。そのくらい、ライブが始まった時は気分が高揚してました。そしてライブ初めの歌詞入りの桜井さんの声が聞こえた瞬間、桜井さんがそこにいると、いつも思います。そのくらい幸せな時間の始まりでした。

Monster

まさかの2曲めでした。いや、後から言うのは簡単ですが、この曲は絶対ライブでやると思ってました。コンセプトがあってるなと。(たまたま)そしたら、SINGLESの後、ナカケーのベースが入って、変な声が出ました。笑 個人的にスパファンドームの光景が思い浮かんだ。

himawari

この曲もまさかの早い。このタイミングですよ。アルバムのリテイクバージョンは荒々しさが減っていて好きではなかったのですが、ライブの桜井さんを見てたらやっぱり荒々しくなってました。うん、とても良いでした。

幻聴

リフレクの横アリを思い出しました。実は色々と思い出深い公演なので。この辺りで、ニューアルバム発売前のミスチルの見方を思い出していた。

HANABI

初めて来た人にもまた来てくれた人にも、この出会いを祝してこの曲を送ります。みたいな感じで曲が始まった気がする。ライブ的にもここでこの曲はバランスが取れていたなとも思います。

NOT FOUND

実は入りのJENのドラムソロ聞いて、ロックンロールかと思いました。残念。。でも、NOT FOUND好きです。Cメロはそんなに桜井さん叫ばず。

忘れ得ぬ人

ピアノが美しい。実は、今日桜井さんは喉の調子は悪くはないですが二日目と言うことで疲れを引きずっている感じでした。ところどころ霞みます。なので、高温続きのこの曲をファルセット多めで歌っていたのは、1個人として印象的でした。

花 -Memento-Mori-

ここは花道での演奏。演出がよかったです。4人花道に縦に並んで演奏。花道の真ん中には上から幕が降りていて、そこに4人の映像が大きく写ったりしてました。私はちょうど桜井さんの正面!やばかった。けど実は田原さんの後ろ姿と間奏の時の4面にアップされた手元がかっこよかった。桜井さんは曲前に、今曲はホテルに缶詰になって、最後の日の休みにしていた日、ちょうど草野球をしているときに(センター)降ってきたらしいです。雨が、、曲のタネの雨が笑 だからPVは野球やっている4人が出てくるんですね!

addiction

これも花道だったかな?垂れ幕に写っていた映像が、男女のオブジェみたいなもので、とてもミスチルのライブらしい映像となっていました。コバタケさんを思い出しました。

Dance Dance Dance

田原さんかっこよすぎ、田原さんが花道に出てきてくれて、楽しそうに弾いてました。見ているだけで幸せ。2番からはナカケーが花道に!スライドがかっこよし!こんなに注目して2人を見たのは初めてだったかもしれません。

ハル

花道の上に大きいレースが吊るされてふわふわと雲のようになってました。青い照明と歌とそれで、雰囲気は一気に寂しげな雰囲気。そしてラスト花吹雪とピンクの照明で、レースが一致に色づいて桜に!個人的にとても好きな演出でした。今回一番重力と呼吸を感じました。

and I love you

息の詰まる演奏。素晴らしかったのですが、昔のライブを超えては来なかったなと個人的な感想。念のためですが、十分素晴らしかったです。

しるし

なんだかんだ、初めて生で聴けた曲(東京だけ切られたり、ライブ当たらなかったり)で、一度は生で聴きたいと思っていた曲。聞き入りました。本当にいろんな気持ちを抱きながら聞いて、気づいたらもう2サビ終わっていたのにずっと長い間演奏されていたような気分になりました。?ホントです。とてもとても聴けてよかった。

海にて、心は裸になりたがる

ラスサビの前、桜井さんはナカケーを指差し、そしてナカケーはラスサビ前の叫びを桜井さんに振られたマイクで歌う!

擬態

この辺はもう重力と呼吸ではなく、ミスチルのライブ!それにつきた。

Worlds end

ここもミスチルのライブ!結局新たな挑戦もあったけど、ミスチルは今までの積み上げ全てでミスチルでした。

皮膚呼吸

Aメロドラムは同期音源。これは、曲にメリハリをつけるための苦渋の決断だったでしょう。この曲はニューアルバムの中で一番好きです。潜水にも似てますよね。ただ、CD音源の完成度が高いのでそれぞれ違ったよさがありましたが、一番身構えていたここでは泣けず。

here comes my love

ここからアンコール。ヒアカムはDL音源を聴きすぎたのであまり感想はありませんでした。。ちょっともったいなかった。

風と星とメビウスの輪

はいきました。これはもう聞いたもん勝ち。間奏の桜井さんの雄叫びで泣きます。全てが桁違いで全ての曲を凌駕してきます。本当にこの曲はすごいのです。スパファンは1,2を争う名盤ですがその中でも秀でて良い曲です!照明の演出も素晴らしい!これはホント生で観れてよかった!一生の思い出です!!ホントこれはマジ。

秋がくれた切符

桜井さん座って歌う。ちょうど去年の秋頃(2017)にできた曲。桜井さんはちょうどこの時期が好きだそうで。

Your Song

ニューアルバムで2番目に好きな曲。結局のところ今回のアルバムのミスチルの気持ちはこの曲に詰まっているし、この曲で完結していると思っています。ミスチルのそして僕らの曲でした。

まとめ

個人的にリフレク以来の横アリでしたが、リフレクが一番好きで、そこに並んでくるライブという感想。後半はライブ感に溢れたものの、前半はアルバムのコンセプトに忠実といった印象でした。特に、私は今回のニューアルバムが未だ馴染めません。個々の曲は力を持って良いのですが、アルバム全体を見た時に、ミックスや音作りが似通ってしまっていると感じます。重力と呼吸になぞらえるのであれば、重力が強すぎ。ミスチルの自由奔放を飛び回る曲づくりの良いところがあまり見られないと感じていました。(あくまでアルバムのバランス的にですよ?笑) そういった意味で、このライブは既存曲を非常にうまく利用して、これが求めていたアルバム像なのかなと感じられるものとなっていたと思います。

演出の方は今回は満点です。違う演出を比べるのは難しいですが、かっこよく映えていたと思います。床に映像が写っていたり、花道の4人の並び、垂れ幕、レースに、ステージのモニターの移動や、中心頭上のケーキのような塔のような演出。レーザを使った音との連動。何と言ってもハルの演出はその場にいないと伝わらない素晴らしさ。リフレクの時の一貫した演出とは別の良さがありました。
スマホライトはまだありましたが、気にするだけ損です。私はあの中で一番アンコールでまたMr.Childrenが出てきて欲しいと願って、一番大きな拍手を送ってしました!もうそう思ってます!そのくらい、Mr.Childrenが好きだし、4人の楽しそうに演奏している姿に力をもらいました。

最後に

今回はニューアルバムが好きになれず、少し不安のあった公演。蓋を開けてみれば今までのMr.Childrenがいて、新しいMr.Childrenがいて、そして今までがすべて詰まった彼らがいました。それだけで、まず十分なライブでした。あとは、、もう察してください。また次も行けるように!以上 f:id:thinline196:20181201013943j:plainf:id:thinline196:20181201014000j:plainf:id:thinline196:20181201013948j:plain

NICTのポートスキャン来てた

すっかり忘れてました

他の人がハニポで観測しているのを見て思い出しました。

公式のお知らせ

公式からのお知らせによると、11月14日(水) に開始し、来年1月末までを目途に継続して行われるとのこと。その際使用されるIPアドレスは、210.150.186[.]238, 122.1.4[.]87, 122.1.4[.]88だそうです。 日本国内でインターネットに接続されたIoT機器等に関する事前調査の実施について | NICT-情報通信研究機構

210.150.186[.]238

f:id:thinline196:20181129001410p:plain f:id:thinline196:20181129001428p:plain

122.1.4[.]87

来てない!涙

122.1.4[.]88

来てない!涙

まとめ

結果的に今観測できていたのは210.150.186[.]238からのみ。スキャンを受けたポートは80(http), 81, 2222(ssh), 2223(telnet), 2323(Philips製のTV)の5種類。(22,23ポートはハニポの都合で2222,2223で受けている) 事前告知されていた22, 23, 80をはじめ、miraiで狙われているポートとして2323がスキャン対象になったと考えられる。81ってなんだっけ、、 (wikiだとTorだった) ASNは全てNTT PC Communications, Inc.となっていた。

rubyチュートリアル12章 メモ

隠しフィールド

form_forを利用したフォーム内に隠しフィールドを設定する。

<%= form_for(@user, url: password_reset_path(params[:id])) do |f| %>
      <%= render 'shared/error_messages' %>

      <%= hidden_field_tag :email, @user.email %>

      <%= f.label :password %>
      <%= f.password_field :password, class: 'form-control' %>

      <%= f.submit "Update password", class: "btn btn-primary" %>
<% end %>

隠しフィールドの定義の仕方で値へのアクセス方法が変わる。hidden_field_tag :email, @user.emailとした場合、params[:email]でアクセスでき、f.hidden_field :email, @user.emailとした場合、params[:user][:email]となる。

時間の比較

checkpoint_at < 2.hours.ago

checkpoint_atはdatetime。< 記号を「〜より早い時刻」と読む。"checkpoint_atが現在時刻より2時間以上前 (早い) の場合"にはtrueとなる。個人的には2時間より先(<)(遠く)にチェックポイントの時間があると読むとしっくりくる。(遠近法で遠いと小さいみたいな)

errors.add

バリデーションに対するエラーを出力する方法として準備されている。 Active Record バリデーション | Rails ガイド
デフォルトでは下のような使い方をするが、チュートリアルでは予め決められた表示形式を利用する形を使った。

user.errors.add(:password, "は以下の文字を含むことができません !@#%*()_-+=")


バリデーション失敗時に上のコードを書いて再描画させることで間違いがあったフォームがハイライトされる。おそらく、name属性値から繫がりを調べてフォームを特定していると思われる。ちなみにform_withを用いて生成したフォームは下のhtmlに変換されて出力されいた。

<%=form_with model: @user, url:password_reset_path(params[:id]), local:true do |f|%>
...
 <%= f.password_field :password, class: "form-control"%>

#変換後
<input class="form-control" type="password" name="user[password]">


ruby チュートリアル11章 メモ

ActionMaier

Railsに標準で組み込まれている、メールを送信してくれる機能。text形式とhtml形式のテンプレートメールを生成する事ができ、宛先や件名含めコントローラから簡単に生成する事ができる。メイラーの生成は下のコマンド。後ろの二つは追加するメソッド名を指定している。

$ rails generate mailer UserMailer account_activation password_reset

実行すると、app/views/user_mailer/account_activation.text.erbapp/views/user_mailer/account_activation.html.erbの様に2つのテンプレートが生成される(password_reset)も同様。

アカウント有効化リンクの生成

#前回
edit_user_url(user)
#生成されるurl
http://www.example.com/users/1/edit

#今回
edit_account_activation_url(@user.activation_token, ...)
http://www.example.com/account_activations/q5lt38hQDc_959PVoo6b7A/edit

上の生成されたリンク内のトークンへeditアクション内ではparams[:id]でアクセスできる。

url内@エスケープ

上で生成したurlにメールアドレスも含める場合、@エスケープする必要があるが、これはメソッドが自動で行ってくれる。

edit_account_activation_url(@user.activation_token, email: @user.email)
#生成されるurl
account_activations/q5lt38hQDc_959PVoo6b7A/edit?email=foo%40example.com

editアクション内ではparams[:email]でアクセスできる。

RSpecでのmailerのテスト

RSpecを普通に入れいていれば、チュートリアルの説明と同じ形のテストファイルがRSpec内にも生成される。ので、同じ手順に沿って進めて問題ない。

メソッドの抽象化

チュートリアルではauthenticated?メソッドを例に挙げている。今まで実装していた、リメンバートークンを比較するメソッドは下。

# トークンがダイジェストと一致したらtrueを返す
def authenticated?(remember_token)
  return false if remember_digest.nil?
  BCrypt::Password.new(remember_digest).is_password?(remember_token)
end


これをsendメソッドを用いる事で、柔軟に変数へアクセス可能となる。文字列、シンボルを渡す事が可能。

def authenticated?(attribute, token)
  digest = self.send("#{attribute}_digest") #モデル内に定義されているのでselfは省略可能
  return false if digest.nil?
  BCrypt::Password.new(digest).is_password?(token)
end

form_with使用時のエラー表示

下のサイトに書いてありますが、form_withを使用するとデフォルトではvalidation時のエラーが表示されない様です。local:trueにする事で、解決します。

    <%=form_with scope: :session, url:login_path,local: true do |f|%>

Rails 5.1のform_withでViewにvalidationエラー表示 - Qiita

アカウント有効化のフィーチャーテスト

チュートリアルでは、ユーザがサインアップしてから有効化のリンクを踏んでログインできるまでをまとめてテストしている。rspecで再現するなら、capybaraを利用して行うが、capybaraがコントローラ内のインスタンス変数が取れないので、生成されたactivation_tokenを取得できず、有効化のリンクを生成できない。代わりの手法として、生成されたメールから正規表現でリンクを取得してみた。チュートリアル上のテストではメール自体のテストを網羅できていないので、フィーチャーテストとしてはむしろ良くなったようにも見えます。

activation_url = expect(ActionMailer:: Base.deliveries.last.body.encoded).to match("^http.*?#{CGI.escape(user.email)}")


他の案としては、コントローラテストで個別に書くとか(コントローラ内からならインスタンス変数にアクセスできる)