ログインの有無で表示するメッセージを変える

RailsでWebアプリを開発しています。 ログインの有無でコメント入力フォームの表示させる内容を切り替えたいときに、以下の記述を使いました。HTMLテンプレートにはSlimを使っています。

    - if logged_in?
        = render 'comments/form', post: @post, comment: @comment
    - else
      .m-3
        | コメントするには
        = link_to 'ログイン', login_path
        | してください

logged_in? は認証に利用しているsorceryのメソッドです。 ログインしている場合は、コメント入力フォームのパーシャルを呼びます。 ログインしていない場合は、ログインの入力を促すメッセージとログインページへのリンクをつけています。

メンターの方に聴いたところ、POSTメソッドでは表示を切り替えることが多いそうです。 GETの場合はControllerで制御することもするそうです。

ログイン有無などユーザーの状態を意識して、システム側から応答する内容を考えて実装していくとすこしずつ良いアプリになっていくような気がします。

Railsでのいいね機能の実装ではまったところ findとfind_byの違い

今日は、画像投稿アプリのいいね機能を実装していました。

User,Postとのアソシエーションは以下のように1対nになっています。

User 1-n Like n-1 Post

したがって、likesテーブルには、user_idとpost_idの組み合わせがレコードとして挿入されるような実装になります。 Likeテーブルのcreateメソッドで正しい値がはいらず苦戦しました。気づいてみれば単純なことですが、findとfind_byの仕様の違いでした。

以下のような実装をしていました。

実装内容

_like.html.slim

= link_to likes_path(post_id: post.id), method: :post, remote: true do = icon 'far', 'heart', class: 'fa-lg'

likes_controller.rb

class LikesController < ApplicationController
  def create
    binding.pry
    @post = Post.find(params[:post_id])
    current_user.like(@post)
  end
end

※ likeというUserモデル内のメソッドでLikeテーブルに挿入するようにしています。

確認したこと

post_id が2のPostについて、いいねのボタンを押して実行したところ、railsサーバーのコンソール表示では以下のようなレコードが挿入されました。

Like Create (3.3ms) INSERT INTO `likes` (`user_id`, `post_id`, `created_at`, `updated_at`) VALUES (2, 1, '2019-10-27 19:07:58', '2019-10-27 19:07:58') 

post_idが2のPostにLikeをしたはずなのに、ずれた値が挿入されています。

よくよくソースをみかえしたところ、controllerで

@post = Post.find_by(params[:post_id]) 

の部分を

@post = Post.find(params[:post_id])

にしなければいけないことに気づきました。

上記のInsert分の前にfindしている部分のSQLのSELECT文をみると

 Post Load (2.0ms) SELECT `posts`.* FROM `posts` WHERE (2) LIMIT 1

のようになっています。これはエラーにならずにWHERE句の文がtrueになって一番最初のPostが返却されるようになっていました(だから post_id が1) find_byの部分をfindに変えたところ、以下のように変化して、正常にInsertされるのが確認できました。

Post Load (6.9ms) SELECT `posts`.* FROM `posts` WHERE `posts`.`id` = 2 LIMIT 1

「findはidを検索するもの、find_byは引数を指定して検索するもの」 という理解はしていたのですが、いろいろ試行錯誤しているうちにfind_byのままにしてしまったようです。

間違えた場合に、エラー制御してくれると暗黙的に期待していたようで、気づくのに時間がかかりました。アソシエーションがやや複雑でidが複数あるので、それを整理するのを先にやったほうがよかったかもしれません。

テストを先に書くようにするか、そうでなければ発行されるSQLをよくよく観察するという習慣が必要だと感じました。

(所要時間 45分)

Railsでの非同期更新処理CRUD DOM操作

今日は、現在作成しているインスタクローンなアプリのコメント機能を実装していました。

コメント機能は、Ajaxを使って非同期更新で実装しています。 それぞれのDOM操作についてまとめます。  ※エラーハンドリングは省略しています

create.js.slim

  | $('.comments-box').prepend(
      $("#{escape_javascript(render 'comments/comment', comment: @comment)}")
      .hide().fadeIn('slow')
    );
  | $('.input-comment-body').val('');
  • comments-box の先頭にcomments/_comments.html.slim を入力したコメントの内容で追加
  • 追加するときのアニメーションはfadeIn()メソッドを使用します。
  • 2行目は、formの内容をクリアしています。

destroy.js.slim

| $('#comment-#{@comment.id}').fadeOut('fast', function(){
    $(this).remove();
  });
  • id が #comment-#{@comment.id} の要素を削除します
  • 単純に remove().fadeOut()のようにしてもfadeOutが効かなかったため、調べたところ、fadeOutの引数として、removeのメソッドを利用すると効くことがわかりました。

update.js.slim

  | $("#comment-#{@comment.id}").html(
      $("#{escape_javascript(render 'comments/comment', comment: @comment)}")
      .hide().fadeIn('slow')
    );
  | $("#comment-edit-modal").modal('hide');
  • updateはhtmlメソッドを使って、 コメントの中身を入れ替えます。ちょっと余計かなと思いましたが、どこが変わったかわかりやすいのでアニメーションをつけました。
  • .modal('hide')で更新後、編集のmodalを消しています。

10/6 日曜 日報 23日目

今日は勉強会に参加した。

会場に向かうまでに大幅に道を間違えたり、雨で駅前ですっ転んだり散々だったが、勉強会は非常に勉強になった。

 

やはり、同じ立場で同じ目標を持つ人達と時間をとって対面でいるという時間は非常に有用だと感じる。

 

なんとなく不安に思っていることがクリアににあり、自分のやりたいことが明確になっていく感じがする。

 

実際、勉強会に参加すると自分の作業の時間は減ってしまうが、勉強に透過するうちの一部はこのような時間にあてるべきだと感じた。

 

帰りの電車の中で、スクレイピングを使ったアプリを考える。スクレイピング・クローリングはそれほど難しい技術ではないけど、真面目に運用するとなると様々なトピックがあると思うので、技術的挑戦は色々できると思う。

また、自分はOracleの技術者だったということもあり、データ指向のものをつくることでバッググラウンドを強みにできるとも考えている。

はやめにチュートリアルを終わらせて、類似のアプリを作って就活の最低ラインのポートフォリオを作り、そのあとに本格的にやりたいアプリを時間かけて作ろうとざっくりともくろみをたてた。

 

 

作成時間 10分くらい

10/5 日報22日目

すこし更新が遅れてしまった。

この数日間、早朝覚醒気味で、やたらと朝早く起きてしまう。

朝方にRailsチュートリアルの動画ハンズオンで1章分やってから出社するというパターンだった。

勉強時間はとれていることはよいのだが、結構体力的にきつい感じがしてきた。3週間で109.5h勉強していて、一日平均5時間だ。平日は残業はないけど、フルで仕事をしている。少し息抜きが必要かなと思ったりしている。

先は(長引かせたくはないけど)長いので、ペースについてはコントロールしていかないと行けないなと思う。

 

ところで、自分ひとりで勉強を続けているのも独りよがりになったり目標を見失いがちなので、メンターをつけたいなと思い、雑食系エンジニアサロンで質問をしたところ、勉強会に誘われた。

少しメンターとは違うかもしれないが、他の人と一緒になにかやるというのもいい経験になるかなと思い、試しに参加してみることにした。

10/2 日報 19日目

今日は会社で評価があったのだが、自分の評価が思ったよりよく、褒められた。

今の会社の業務には不満はあるけれど、自分がやってきたアウトプットを褒められるのは嬉しい。

 

ただ、やりたくないことで褒められて嬉しいというのは、DV被害者に似た心理もあるので、そのへんは意識しないと無駄な時間と労力を費やしていくことになる。

まあ、美味しそうなところがあればやっていこうというスタンスで。

ちょっとグループ会社でRubができそうな会社があるので、そこへの出向とかどうかなと思ったりもしている。

 

古い文章だが、匿名はてなでいい文章を見つけた。

希望を失った男がプログラミングで救われる話。映画化してほしい。

 

 

10年間を振り返ってみて思う。あの頃と比べて、何か変わっただろうか?

家族や親類とは縁が切れたままだし、いまだに人付き合いは苦手だし、金はないし、夢も希望もない。それは今でも変わらない。ただ、あの頃あれほど感じていた空虚さは、跡形もなく消えている。

西成の高架下で見た光景を思い出す。ガラクタ解体していたおっちゃん。あのキラキラした目。たぶんあの瞬間に僕は、自分にとって一番大切なものは何なのか、心の深い部分で理解したんだと思う。

世界一周だなんだというのも本当はどうでもいい。僕はただ、いつだってドキドキしていたいのだ。

初めて人を好きになったときの気持ち。知らない街で暮らし始めたときの気持ち。そして、プログラムが思い通りに動いたときの気持ち。

それを持ち続けていたいのだ。いつだって新しい世界にワクワクしていたいのだ。

だから僕は、今日ガラクタのようなコードを書き続けている。

ふと目を閉じれば、まぶたの裏に映る、あの日のメッセージ

"Hello world!"

 

 

作成時間 5分くらい

 

10/1 日報18日目

Web系エンジニアでYouTuberの勝俣健太氏の主催する「雑食系エンジニアサロン」に入会した。目的は、Web系エンジニアを目指す人が使うポートフォリオが見ることができるため。実際にこういうものが現職エンジニアから目に叶うのだなと知ることにより、ゴールイメージをわずかばかりにもつことができた。これで980円なら安い。

 

https://kentakatsumata.net/archives/10

 

今日は、夜に眠れず睡眠不足の状態で出社した。

睡眠不足だとパフォーマンスが落ちるだけでなく、メンタルにも確実に悪いのでほんとうに大敵だなと思う。

勉強しながら働いている以上はこれを一番の優先度にしてもいいくらいだと思った。

 

 

作成時間 5分くらい