はじめに
RUNTEQ卒業時のポートフォリオ制作として、Webサービスを作成しましたので、ご紹介させてください。
サービス概要
「子どもが小さいうちは、親が近くにいてあげないとダメよ」
「子どもにピアノを習わせなさい」
「母乳で育てなさい」
・・・
子育てをしていると、親を惑わせる様々な囁きが聞こえてきます。
気にしない気にしない!と思っていても、両親/義両親や仲のいいママ友に言われたりしたら、ものすごく気になってしまうもの。
そんなとき、 「科学的には、それは正しいとは言えない」 なんて言える勇気が欲しいとは思いませんか?
ということで、 気軽に子育ての科学的根拠(エビデンス)に触れられるサービス を作ってみました。
サービスはこちらです。
https://konotame.herokuapp.com
このサービスでできること
1. エビデンスを読む
現在のところ不定期更新ですが、子育てに関する科学的根拠(エビデンス)をご紹介しています。
2. 質問や回答を読む•投稿する•いいねやブックマークをする
他のユーザーの意見ももちろんエビデンスのひとつですので、何か聞いてみたいことがあれば、質問を投稿することもできます。他のユーザーの質問に対して回答を付けることもできます。運営事務局の方で、関連エビデンスをピックアップすることもあります。
ユーザー登録をしていない場合は、閲覧のみ可能です。
3. 質問やエビデンスを人気順で閲覧・質問の閲覧履歴が残る
ユーザー登録をすると、トップページに人気順で質問やエビデンスが並びます。また、質問の閲覧履歴も残ります。
使用した技術
バックエンド & フロントエンド
- Ruby on Rails 7.0.3
- TailwindCSS
外部API
- Google Cloud API
- Twitter API
サーバ
- heroku
苦労したところ
button_to
rail7になって変更になったらしいのですが、link_to
ではmethod: :delete
、つまり、ログアウトや削除ができなくて大変困りました。
うまくいかなかったコード:
<%= link_to (t 'defaults.logout'), logout_path, method: :delete %>
うまくいったコード:
<%= button_to (t 'defaults.logout'), logout_path, method: :delete %>
こんな感じで、link_to
をbutton_to
に変更することで、解決。
polymorphic関連 + 単一テーブル継承
今回、tagとcategoryのカラム構成が似たようなものなので、これらを一緒にtaxonomyテーブルに保管することにしました。(単一テーブル継承)
また、evidenceとquestionは、同じようにtagとcategoryを持つので、evidenceとquestionをarticableとして、taxonomyと紐付けを行うこととしました。(polymorphic関連)
つまり、evidenceテーブルのidがarticle_tagテーブルにおけるarticable_idに対応し、同様に、questionテーブルのidがarticle_tagテーブルにおけるarticable_idに対応しているという状態です。
polymorphic関連と単一テーブル継承を紐づけた記事が見当たらなくて、エラーを連発しましたが、モデルファイルを丁寧に記載することでなんとか動くようになりました。
class Taxonomy < ApplicationRecord
validates :name, presence: true
end
class Tag < Taxonomy
has_many :article_tags, dependent: :destroy
has_many :evidences, through: :article_tags, source: :articable, source_type: "Evidence"
has_many :questions, through: :article_tags, source: :articable, source_type: "Question"
end
source_type
を記載し忘れるとうまく動きませんでした。
class Category < Taxonomy
has_many :evidences
has_many :questions
end
class ArticleTag < ApplicationRecord
belongs_to :tag
belongs_to :articable, polymorphic: true
end
polymorphic: true
を入れていないとうまく動きませんでした。
class Evidence < ApplicationRecord
belongs_to :category, optional: true
has_many :article_tags, as: :articable, dependent: :destroy
has_many :tags, through: :article_tags, as: :articable
(中略)
end
class Question < ApplicationRecord
belongs_to :category, optional: true
has_many :article_tags, as: :articable, dependent: :destroy
has_many :tags, through: :article_tags, as: :articable
(中略)
end
複雑な関係に頭の中が混乱し、何度もテーブルを全て削除して、polymorphic関連も単一テーブル継承もやめてやろうかと思いましたが、これも練習と踏みとどまり、なんとか完成させることができました。
でも、面倒なので、もうこんな形では作らないかも、、、
turbo-railsの利用
rails7から、Hotwireというのがデフォルトになったようなのですが、 リンクやフォームからのリクエストが非同期リクエストになり、サーバーがHTMLをレスポンスする そうです。それによってajaxのような非同期通信っぽい挙動が実現できるようです。
こちらのページに詳しく説明があり、参考にさせていただきました。
その Turboを使うためのgemとして、turbo-railsを利用しました。
いろんな参考ページを見て作ろうとしたものの、まったく分からず、スクールで分からないと言っていたら、なんと、スクールの方がご自分のGitHubのURLを送って教えてくださいました!!
本当にありがたいです!!
ここでは、私のアプリで、回答にいいねをする機能をピックアップします。
1. コントローラー
class LikeAnswersController < ApplicationController
def create
@answer = Answer.find(params[:answer_id])
current_user.like_answer(@answer)
end
def destroy
@answer = current_user.like_answers.find(params[:id]).answer
current_user.unlike_answer(@answer)
end
end
ここの、like_answer(answer)
, unlike_answer(answer)
メソッドは、モデルファイルで定義しております。
2. モデルファイル
class User < ApplicationRecord
(中略)
def like_answer(answer)
like_answers_answers << answer
end
def unlike_answer(answer)
like_answers_answers.destroy(answer)
end
def like_answer?(answer)
like_answers_answers.include?(answer)
end
end
3. ビューファイル
<%= turbo_stream.replace(dom_id(@answer, :like_answer), partial: 'answers/unlike',locals: { answer: @answer }) %>
<%= turbo_stream.replace(dom_id(@answer, :like_answer), partial: 'answers/like',locals: { answer: @answer }) %>
<% if current_user.like_answer?(answer) %>
<%= render 'answers/unlike', { answer: answer } %>
<% else %>
<%= render 'answers/like', { answer: answer } %>
<% end %>
<%= turbo_frame_tag dom_id(answer, :like_answer) do %>
<%= button_to like_answers_path(answer_id: answer.id), method: :post do %>
<%= icon 'far', 'heart' %>
<%= answer.like_answers.count %>
<% end %>
<% end %>
<%= turbo_frame_tag dom_id(answer, :like_answer) do %>
<%= button_to like_answer_path(current_user.like_answers.find_by(answer_id: answer.id)), class:"text-red-500", method: :delete do %>
<%= icon 'fas', 'heart' %>
<%= answer.like_answers.count %>
<% end %>
<% end %>
外部認証
サイトでのユーザー登録・ログイン以外にも、GoogleアカウントおよびTwitterアカウントでもログインできるようにしました。
Twitterログインに関しては、記事にしました。
おわりに
これまでの生活にプログラミングという新しい項目がプラスされてしまったので、それによって、子どもたちとの時間が減ってはいけないと思い、子どもたちが寝た後に、夜な夜な開発していました。
6月の終わり頃から開発を開始し、途中新型コロナに感染したりしながら、10月になんとか本リリースまでこぎつけることができました。
子育てをしながらプログラミング学習、アプリ開発って、とてもとても大変なことです。
「子育て中にアプリ開発をしているけど疲れてしまったよ」と言う方がいらっしゃれば、 こんな風に少しずつ進めても、ゴールにはたどり着けますので、 焦らず進めていただきたいと思います。
開発中は、 スクールの技術面談 で問題を解決していただいたり、日誌などに「できない」とつぶやくと、 スクールの方々が解決策を書き込んでくださったり、 たくさんの方に助けていただきました。
この記事がどなたかのお役に立てれば幸いです。
コノタメをぜひ使っていただき、ご意見・ご感想などいただけましたら幸いです!