このアプリは、我々と 約9,500年もの付き合いがありながら、未だ謎だらけの存在「ネコ」に関する日常のあれやこれやから真髄にいたる高次元なものまで、あなたが抱える悩みをざっくばらんと、そして包括的に相談できる総合相談サイトです! きっとネコの使徒達が、あなたの悩みに答え、ネコを和解へと導いていくことでしょう。
https://nekoto-wakaiseyo.herokuapp.com/
Basic認証が必要です。サイト訪問時に出現するフォームに以下を入力してください
- 認証ID: miwa
- PASS : 2078
相談投稿者用アカウント
- アドレス : test@test.com
- パスワード : 11111q
回答者用アカウント
- アドレス : test4@test.com
- パスワード : 11111q
現在、猫はペットとして国内において約900万頭もの数が飼育されています。しかし、これだけの飼育頭数がいるとなると、そこで発生する問題は様々です。大抵の場合、健康のことであれば近くの動物病院に、飼育に関する基礎知識であれば、購入時にペットショップ等で情報を得ることができます。しかし、実際に起こりうる問題は個体や飼育環境により千差万別。「こんなはずじゃなかった」と、最終的には自ら保健所へ猫を引き渡したり、遺棄したりするケースが後を経ちません。
一方、相談する場としてWeb上には専門家による相談サイトが存在しますが、運営側の都合、時間がかかるケースが多くあまり認知もされていません。また、大手掲示板のようなサイトで相談することも考えられますが、あくまで全体のカテゴリーの一つとしてあまり専門性はありません。さらに、現在のネットユーザーの多くはTwitterのようなSNSを相談や情報収集の場に利用していますが、こちらは140文字(全角)という文字数制限があり、より具体的な相談はしにくい状況となっております。相談者が求める回答と閲覧者が想像する回答に齟齬が発生する可能性が高く、それが元に余計な言い争いや誹謗中傷が発生するケースが散見されます。
そこで、今回私は完全に猫に特化し、かつ包括的な話題に対して具体的な相談ができる相談サイトを制作しようと考えました。フォームの入力により、問題に至るまでの背景や状況を「前提」として表示することにより、なぜその人が困っているのか、その人に寄り添った回答を求めることができるのではないかと考えました。
それが今、人類に課せられた課題であり、私に与えられた使命なのです。
- アカウント登録
- アカウント編集
- アカウント削除(論理削除)
- ログイン/ログアウト
- 相談投稿
- 相談編集
- 相談削除
- 相談一覧参照
- 相談詳細参照
- コメント機能(Ajax / ActionCable)
- 回答締め切り
- 回答作成
- 回答一覧参照
- 回答詳細参照
- コメント機能(Ajax / ActionCable)
- レビュー機能(Ajax)
- プロフィール作成
- プロフィール編集
- プロフィール詳細参照
ログイン状態では以下のメニューが表示されます
- 「マイページへ」 ・・・プロフィール詳細ページへ
- 「アカウント編集」・・最初に登録したアカウント情報を修正するページへ
- 「ログアウト」・・・・文字通りログアウトします
- 全部の項目が初期値のまま「保存」ボタンを押してもスキップになります
- どれか一つでも入力したり選択するとあなたのプロフィールが完成です
- ユーザーアイコンを変更したい方は画像をアップロードしてくださいね!
- ヘッダーメニューから「相談する」をクリック!
- 全ての項目を埋めると相談を投稿できます(画像は任意です)
- 表示された相談のタイトルをクリックするとその相談の詳細ページに遷移します
- 詳細画面では自身が投稿した相談に対して編集や削除ができます
- ただし、コメントや回答が寄せられた場合、削除はできなくなりますのでご注意ください
- 他の人が投稿した相談の詳細ページから、回答作成ページに遷移できます
- 回答情報はすべて埋める必要があります(画像は任意です)
- 表示された回答のタイトルをクリックすると、回答の詳細ページへ遷移できます
正直な話、プログラムを書いていた時間以上にテストに時間をかけていたように思います。そのおかげもあって、テストでは特定の要素や値を取得する方法についての見識はかなり深まったように感じます。また、環境により同じコードでも失敗する可能性があることも学びました
- できるだけ再現性の高いテストを実施(
sleep
の極力排除) within
でテストのスコープ(範囲)を限定し、同じ要素の重複によるエラーを排除
アソシエーションを組んだ要素をどのようにDBから抽出するか、という点については強く意識しました。
- 不安定な挙動をする
includes
メソッドではなく、joins
やpreload
メソッドを用いて必要最低限なクエリの発行を意識 - 一度定義した変数を活用したクエリの発行
JavaScriptファイルが読み込まれない可能性があるためひとまずTurbolinksをoffにするという手法をこれまで取ってきましたが、今回はそのTurbolinksの利点を殺さずに導入できないかと模索した結果、なんとか同居させることに成功しました。
↓ その時のQiita記事です
【Rails6】Turbolinksを同居させたままActionCableで非同期通信コメント機能を実装したい!
ウィザード形式のユーザー登録を考えた場合、フォームの情報をセッションに一時保存して、次のページでのフォーム送信時に別々のテーブルに登録するという方法が考えられますが、途中のページでURL入力により途中離脱された場合のセッションをどのようにするかという考えに至りました。
そこで今回の実装では、プロフィール登録のページは一旦表示させつつ、任意で、という形式をとることにより、セッションを利用せずともウィザード形式を装いつつ、独立させた形でユーザー情報を作成することを可能としました。 この方式を取ることにより、プロフィールを作成したくないユーザーの分だけデータレコードを削減することができ、DB容量の圧迫を防ぐことに一役買っていると考えます。
とにかく DBの設計に無駄がないように! を心がけました。 アソシエーションによってできることを最大限に活用すべく、テーブルの中に余分なカラムを作らないことを意識しました。
- コメントテーブルを2つに分割
- 文章のカラム型をtextとstringに分割。それぞれの許容量を知る
- 改めてDB設計とSQLを学ぶ意欲が向上
- 「null」が入るカラムを極力無くすように設計。SQLでクエリ発行時に意図しない挙動を起こさないように配慮
- 一方、userモデルに論理削除を実装するのであれば、usersテーブルにdeleted_atカラムを追加するのではなく、別に削除されたことを記録するテーブルを作成すればよかったのでは…?
全ページ、水平方向に対してレイアウトが変更されるように実装しました 今回は初めてscss(sass)を使用し、記述量が減るようにと意識したところでしたが、まだまだ改良の余地があります。
※現在原因究明中です
- カテゴリー別相談一覧表示機能
- ページネーション機能
- タグ機能
- 検索機能
- レスポンシブ対応(スマホ版ブラウザでのJsファイルの作動)
- 通知機能
- ユーザーテーブル論理削除の見直し
- ruby
2.6.5
- rails
6.0.4.4
- activestorage
6.0.4.4
- actioncable
6.0.4.4
- mysql2
0.4.4
- sass-rails
5.2.1
- webpacker
4.3.0
- turbolinks
5
- rspec-rails
4.0.0
- active_hash
3.1.0
- aws-sdk-s3
1.112.0
Column | Type | Options |
---|---|---|
nickname | string | null: false, unique: true |
string | null: false, unique: true | |
encrypted_password | string | null: false |
deleted_at | datetime |
- has_many :consultations
- has_many :answers
- has_many :cons_comments
- has_many :ans_comments
- has_one :profile
- has_many :reviews, through: :answers
Column | Type | Options |
---|---|---|
age | integer | null: false |
job | string | null: false |
skills | string | null: false |
address | string | null: false |
cat_exp | string | null: false |
family_type | integer | null: false |
house_env | integer | null: false |
my_cats | text | null: false |
introduction | text | null: false |
user | references | null: false, foreign_key: true |
Column | Type | Options |
---|---|---|
cons_title | string | null: false |
category_id | integer | null: false |
summary | string | null: false |
situation | text | null: false |
problem | text | null: false |
user | references | null: false, foreign_key: true |
- belongs_to :user
- has_many :answers
- has_one :reconciliation
- has_many :cons_comments
Column | Type | Options |
---|---|---|
rec_text | string | null: false |
consultation | references | null: false, foreign_key: true |
- belongs_to :consultation
Column | Type | Options |
---|---|---|
cons_c_text | string | null: false |
user | references | null: false, foreign_key: true |
consultation | references | null: false, foreign_key: true |
- belongs_to :consultation
Column | Type | Options |
---|---|---|
ans_title | string | null: false |
ans_text | text | null: false |
user | references | null: false, foreign_key: true |
consultation | references | null: false, foreign_key: true |
- belongs_to :user
- belongs_to :consultation
- has_one :review
- has_many :ans_comments
Column | Type | Options |
---|---|---|
point | integer | null: false |
answer | references | null: false, foreign_key: true |
- belongs_to :answer
Column | Type | Options |
---|---|---|
ans_c_text | string | null: false |
user | references | null: false, foreign_key: true |
answer | references | null: false, foreign_key: true |
- belongs_to :user
- belongs_to :answer
Column | Type | Options |
---|---|---|
tag_name | string | null: false |
- has_many :consultation_tags
- has_many :consultations, through: :consultation_tags
Column | Type | Options |
---|---|---|
consultation | references | null: false, foreign_key: true |
tag | references | null: false, foreign_key: true |
- belongs_to :consultation
- belongs_to :tag