アラフォーがお金持ちになるためプログラマ目指すブログ

お金も根性も学歴もないアラフォーまきのがエンジニア…じゃない、プログラマになってお金持ち目指すよ!

侍エンジニア塾 25回目の授業

どうも、アラフォーまきのです。




2/15(金)に予定通り侍塾あったんですが、その日めっちゃ予定詰めちゃっててブログ書く時間が取れず。



では忘れる前に記録!
今回も長い!ヒー!

授業まで何をしていたか


困ったユーザーの退会処理


削除系は紐付けの大阪ら論理削除に決めたのだけれど、deviseさんはユーザーを物理削除してしまうので、そこをうまく調整してあげたかった。




deviseなどの便利なgemって、良きように全てができているけれど、私のように知識が不十分な人間から見ると、どこで何が起きているのか見えなくて。
(私だけ?)




controllerとかviewもデフォルトでは見えない状態になっていて、上手に付き合うにはまだまだ勉強不足。





結局自力でうまくできず、この日の授業で助けてもらいましたが、ちょっと頑張ればなんとかなったなと反省しました;





削除されたデーターを選択肢から除外するには?



form_withを使って、collection_selectによるプルダウンを作ってあるのです。





たとえば、プルダウンでタグ一覧から該当のタグを選択して絞り込む感じ。





そのタグ一覧の中に、論理削除されたものが出てしまっていたので、それを除いたものをデータ群としてcollection_selectに渡してあげたかった。





結論はできなかった。Ruby書き方忘れちゃって、時間がない焦りとモチ下がりでしっかり調べなかった私の落ち度です;






HTML / CSSを思い出せ!


見てくれについては全く触っていなかったので、もうやり始めてないと間に合わない。
ということで、久々にしっかりHTML/CSS。






侍塾入って最初の教科書をもう一度確認しつつ、亀の歩みのような速度でコード書いて、そのうちなんだか悲しくなってきちゃったんですよね。






一度はできたのに全然思い出せない。
Bootstrapのグリッドシステムのこともすっからかん。




侍塾は残り2回。絶対に終わらない!という絶望感。
(実は、メンターさんと個別にとあるお話を頂いているので、公式には残り2回だけれど…ふふふ。その辺はまた後日)


この日の授業

1:ユーザーを退会させる


さて、論理削除のためdeletedというカラムを追加し、これがtrueなら退会済みとみなすということでここまで進めてきていたんだな。





ユーザーが「退会するよ」ボタンを押しら、deleted == trueにして、ログアウトさせて、ログインできないようにする必要があるんだ。




ログインできないようにするのは前回の授業で解決済みだった。



①まずはactive_for_authentication?のオーバーライド

deviseがもともと持っているメソッドのうち、
「その人アクティブな人?」と確認するメソッド【active_for_authentication?】を、
「deleted == trueだったらfalse(非アクティブ)だよ」とオーバーライドしてあげる。


各場所はuser.rb(model)。



deletedは論理削除のために私が追加したカラムの名前。
boolean型にしたから、trueかfalse。



ちなみに、参考サイトには三項演算子で書かれていたけれど、私にはまだすぐに理解できないので、きちんとifで書き直してみてます。



参考資料
www.rubydoc.info



【user.rb】

def active_for_authentication?
    #super && ! self.deleted   #=>これは三項演算子による記述。砕いて書くと↓になる。

    if self.deleted
      false
    else
      super
    end
 end


②deleted == ture時のエラーメッセージを設定してあげる。


デフォルトでは、非アクティブだッタ時のエラーメッセージが以下となっている。

en:
  devise:
    confirmations:
        :
       inactive: "Your account is not activated yet."
       :


これは「あなたのアカウントはまだ有効になっていませんよ」ということで、「あなたは退会したでしょ」じゃないから、ちゃんと正しいメッセージをだしてあげようってことで。




メッセージはdevise.en.ymlに書かれているそうなので、そこに新しい自作のメッセージを追加しちゃう。




自作メッセージだから、メッセージの内容は好きに書いたらOK。





ただしenとある通りEnglishなので、日本語にしたいならまた後でちょっと調整が必要。





【config/locales/devise.en.yml】

en:
  devise:
    confirmations:
        :
       inactive: "Your account is not activated yet."
       supecial_deleted: "Your account is not active." #=>ここに書き足してみた
  :



③deleted == trueで弾かれる人にはこのメッセージをだしてね!と指定

これも、modelに書いてあげる。さっきのactive_for_authentication?に続けて書いちゃっておk。

【user.rb】

def inactive_message 
    # self.deleted? ? super : :delete  #=>これも三項演算子。砕いて書くと↓になる。

    if self.deleted
      :supecial_deleted  #deleted == trueならこのメッセージを出すようにする。
    else            
      super #:inactiveを返すようだ
    end
end



さあこれでログインはできなくなったけれど、じゃあ退会するってボタン押した後、ログアウトはどうするか?





ここは、私がいろいろああでもない・こうでもないと考えた経緯を伝えてしまったためか、メンターさんもちょっとわからなくなってしまったらしく、「ちゃんと確認しておきたいから、次回の授業の時まで宿題にさせてね」とのこと。
恐縮すぎる;




その次回がこの授業だったわけだけれど、めっちゃ簡単な話で、reset_sessionをつかえばよかっただけだった。




deviseがなんとかかんとか…と難しく考えず、セッションをぶった切るだけでよかったらしい。




私個人は、deviseで制御しているのだから、deviseのログアウトと同じように処理しないと、ログアウトとして扱われないのでは?と思ってた。





だから、調べてもいまいち納得というか、理解できずにどうしたらいいか見つけられずにいたんだ。





以前progateでRailsやった時、ログイン・ログアウトをdeviseを使わずに書くところがあって、sessionをつかって、ユーザー情報をブラウザに覚えさせるよってやったのですよ。





だからsessionを切ることはなんかわかったんだけれど、deviseではそれ用のメソッドとか、フラグ管理みたいのがあるんじゃないか…と勝手に思ってた。





で、調べ方が下手くそで見つけられず…という;




ということで、結果的にこんなコードでうまくいっちゃった。

def delete
    user = current_user
    user.deleted = true
    user.save!
    reset_session  #これでセッション切れてログアウトになる!
    redirect_to ("/")
end

実際には、セッション切る前にこのユーザーに紐づいているmodel達のdeletedをtrueにするコードを書き足すよ。




でも、reset_sessionの一言でよかったというのをみて、すごい脱力感だった。




なんでこれにたどり着かなかったのか。





2:プルダウンからdeleted == trueのものを除外する



これも本当に簡単なことだった。
現状のcollection_selectはこちら

:
<%= form.collection_select :tag_type, @user.tag_types, :id, :name, selected: @user.tag_types %>
<%= form.submit "絞り込む" %>
:


ここの@user.tag_typesっていうのが、選択肢一覧に出されるデータ群の指定になってるんだな。




まず、userとtag_typesは以下のような関係にあるわけだ。

【user】
 has_many: tag_types

【tag_types】
belongs_to: user


で@user.tag_typesってなんなのかっていうと、@userはコントローラで

@user = current_user

ってしていて、ログイン中のユーザー情報を拾ってきてる。



なので、さっきのcollection_selectno@user.tag_typesは、
【ログイン中のユーザーが持っているtag_typesを全部選択肢として表示】ってことになってるわけだ。




論理削除のdeleted == trueとか全く関係なく全て拾われてくるから、削除されたはずのtag_typesも絞り込みに出てきちゃう。






そこで@user.tag_typesの部分を、deleted == falseのものに絞ったデーターを拾ってくるメソッドに置き換えてあげる。




ここで、tag_typesのdeletedがtrueかfalseか?というのに騙されてはいけない。
@user.tag_typesとある通り、「そのユーザーが持っている…」という主語がつく。



だから、メソッドを書く場所はuserが絡む場所。



で、データー群を作りたいわけなので、DBがらみということでuser.rbにメソッドを書く必要がある。




ほー!なるほどw



【user.rb】

def active_tag_types
    tag_types = TagType.where(deleted: false).where(user_id: self.id) 
end

modelではcurrent_userが使えない部分だから、selfで対応。





modelでは、current_userかどうかどうかを知る必要がないから使わないし、使えるようになっていないそうで。





この辺、なんとなくふんわりわかるんだけど、理解がまだ浅くて、ちゃんと書こうとするとわかるように書けない;




話はもどって、今作ったactive_tag_typesさんに@user.tag_typesのところへ入ってもらえばOKと。


:
<%= form.collection_select :tag_type, @user.active_tag_types :id, :name, selected: @user.tag_types %>
<%= form.submit "絞り込む" %>
:


これで、そのユーザーの持っている、deletedがfalseのtag_typesを全部選択肢として使ってね!となる。




ほーんなるほど!




最後に


メンターさんにも話したんですけど、私ゲームすごく好きで色々やるんです。



だけど、自分でエンディングまでみにいったの、2割あるかないかだと思う。




エンディングが近くなると、だんだんやらなくなっていっちゃうんですよ。なんだろうこれ?




終わりが近くなれば、当然飛空挺・船・気球・フラミー・ラーミア、いろんな手段が使えるようになっているから、いろんなところにいけるんですよね。



だいたいそのくらいになると、フラグ立て忘れがあってできないイベントがあったり、ボスが強くて倒せなかったり、ミニゲームが突破できなかったり、そんなのも増えてくるんで、多分そういうのが「めんどうだー」ってだんだんやらなくなっていくのかなあ。




実は今その時と同じ気分なんです!これはマズイ!





途中で書いた通り、この道を進むことにしたのは自分で決めたので、自分自身に責任を持って最後までちゃんとやり遂げたいのです。




別にやり遂げなくたっていいんですよ?
自分が責任もって「この責任から逃れるぜ!」って決めたんなら。




でも、今回は責任もって無責任を宣言するこなんていやだし(侍塾始めるのに家族というチートを使ったし)、メンターさんが私に割いてくれた時間を無駄にするなんてもう絶対に無理!



せっかく私のために、仕事としてきちんと向かい合ってくれて、知識や時間を提供してくれたのだから、それに報いたいし、自分自身この先ちゃんと地に足つけて生きていきたいんだーって思ったはず。





なので、頑張ります。時間はないけれど、無駄にしている時間はたくさんあるはずだから、ちょっとでも無駄な時間を減らして書いていきます!




次回までに、出来るだけ見てくれを整えて、もう本番用プロジェクト立てないとマズイので、どんどん進めていきます!




給料明細がでてるのでその分ブログも書きたいし、無駄は省略!
(といってもう7,000文字で驚く)



ではまた来週!