子育て情報サービス『コノタメ』をリリースしました

# はじめに
RUNTEQ卒業時のポートフォリオ制作として、Webサービスを作成しましたので、ご紹介させてください。

# サービス概要
![スクリーンショット 2022-10-25 10.44.33.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2926004/fd6c2cfe-4e27-636a-0334-4b7eaabc0fb3.png)
「子どもが小さいうちは、親が近くにいてあげないとダメよ」
「子どもにピアノを習わせなさい」
「母乳で育てなさい」
・・・

子育てをしていると、親を惑わせる様々な囁きが聞こえてきます。
気にしない気にしない！と思っていても、両親／義両親や仲のいいママ友に言われたりしたら、ものすごく気になってしまうもの。
そんなとき、 **「科学的には、それは正しいとは言えない」** なんて言える勇気が欲しいとは思いませんか？
ということで、 **気軽に子育ての科学的根拠（エビデンス）に触れられるサービス** を作ってみました。

サービスはこちらです。
https://konotame.herokuapp.com

# このサービスでできること
### 1. エビデンスを読む
![スクリーンショット 2022-10-25 10.55.50.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2926004/7fbed0e2-a379-980a-4e1b-cbd3273fa6d0.png)
現在のところ不定期更新ですが、子育てに関する科学的根拠（エビデンス）をご紹介しています。

### 2. 質問や回答を読む•投稿する•いいねやブックマークをする
![スクリーンショット 2022-10-25 12.18.04.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2926004/0d5bcf63-6221-9f41-b6a2-5ef011682728.png)
![スクリーンショット 2022-10-25 12.18.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2926004/ee790767-a9bc-cc73-65fe-ede077a875e6.png)

他のユーザーの意見ももちろんエビデンスのひとつですので、何か聞いてみたいことがあれば、質問を投稿することもできます。他のユーザーの質問に対して回答を付けることもできます。運営事務局の方で、関連エビデンスをピックアップすることもあります。
ユーザー登録をしていない場合は、閲覧のみ可能です。

### 3. 質問やエビデンスを人気順で閲覧・質問の閲覧履歴が残る
![スクリーンショット 2022-10-25 12.23.28.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2926004/d6ec3760-4877-47e1-5b7a-482c3d07380e.png)
![スクリーンショット 2022-10-25 12.23.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2926004/8c95077c-3845-890d-3a2e-23995cb1d30a.png)
ユーザー登録をすると、トップページに人気順で質問やエビデンスが並びます。また、質問の閲覧履歴も残ります。

# 使用した技術
### バックエンド & フロントエンド
* Ruby on Rails 7.0.3
* TailwindCSS

### 外部API
* Google Cloud API
* Twitter API

### サーバ
* heroku

# 苦労したところ
## button_to
rail7になって変更になったらしいのですが、`link_to`では`method: :delete`、つまり、ログアウトや削除ができなくて大変困りました。

うまくいかなかったコード：
```erb
<%= link_to (t 'defaults.logout'), logout_path, method: :delete %>
```
うまくいったコード：
```erb
<%= button_to (t 'defaults.logout'), logout_path, method: :delete %>
```
こんな感じで、`link_to`を`button_to`に変更することで、解決。

## polymorphic関連 + 単一テーブル継承
![スクリーンショット 2022-10-25 20.33.39.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/2926004/7fce5b81-4d86-c736-163a-01e443f7aad5.png)
今回、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関連と単一テーブル継承を紐づけた記事が見当たらなくて、エラーを連発しましたが、モデルファイルを丁寧に記載することでなんとか動くようになりました。

```ruby:app/models/taxonomy.rb
class Taxonomy < ApplicationRecord
  validates :name, presence: true
end
```
```ruby:app/models/tag.rb
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`を記載し忘れるとうまく動きませんでした。
```ruby:app/models/category.rb
class Category < Taxonomy
  has_many :evidences
  has_many :questions
end
```
```ruby:app/models/article_tag.rb
class ArticleTag < ApplicationRecord
  belongs_to :tag
  belongs_to :articable, polymorphic: true
end
```
`polymorphic: true`を入れていないとうまく動きませんでした。
```ruby:app/models/evidence.rb
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
```
```ruby:app/models/question.rb
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のような非同期通信っぽい挙動が実現できるようです。

こちらのページに詳しく説明があり、参考にさせていただきました。

https://zenn.dev/shita1112/books/cat-hotwire-turbo

その **Turboを使うためのgemとして、turbo-railsを利用しました。**

いろんな参考ページを見て作ろうとしたものの、まったく分からず、スクールで分からないと言っていたら、なんと、スクールの方がご自分のGitHubのURLを送って教えてくださいました！！
本当にありがたいです！！

https://github.com/e601201/modelers_log

ここでは、私のアプリで、回答にいいねをする機能をピックアップします。

### 1. コントローラー
```ruby:app/controllers/like_answers_controller.rb
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. モデルファイル
```ruby:app/models/user.rb
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. ビューファイル
```erb:app/views/like_answers/create.turbo_stream.erb
<%= turbo_stream.replace(dom_id(@answer, :like_answer), partial: 'answers/unlike',locals: { answer: @answer }) %>
```
```erb:app/views/like_answers/destroy.turbo_stream.erb

<%= turbo_stream.replace(dom_id(@answer, :like_answer), partial: 'answers/like',locals: { answer: @answer }) %>
```
```erb:app/views/answers/_like_button.html.erb
<% if current_user.like_answer?(answer) %>
  <%= render 'answers/unlike', { answer: answer } %>
<% else %>
  <%= render 'answers/like', { answer: answer } %>
<% end %>
```
```erb:app/views/answers/_like.html.erb
<%= 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 %>
```
```erb:app/views/answers/_unlike.html.erb
<%= 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ログインに関しては、記事にしました。

https://qiita.com/Amiamiko3/items/9e7b012f2bb266d27e66


# おわりに
これまでの生活にプログラミングという新しい項目がプラスされてしまったので、それによって、子どもたちとの時間が減ってはいけないと思い、子どもたちが寝た後に、夜な夜な開発していました。
6月の終わり頃から開発を開始し、途中新型コロナに感染したりしながら、10月になんとか本リリースまでこぎつけることができました。
子育てをしながらプログラミング学習、アプリ開発って、とてもとても大変なことです。
「子育て中にアプリ開発をしているけど疲れてしまったよ」と言う方がいらっしゃれば、 **こんな風に少しずつ進めても、ゴールにはたどり着けますので、** 焦らず進めていただきたいと思います。

開発中は、 **スクールの技術面談** で問題を解決していただいたり、日誌などに「できない」とつぶやくと、 **スクールの方々が解決策を書き込んでくださったり、** たくさんの方に助けていただきました。
この記事がどなたかのお役に立てれば幸いです。

[コノタメ](https://konotame.herokuapp.com)をぜひ使っていただき、ご意見・ご感想などいただけましたら幸いです！

https://konotame.herokuapp.com