以下は開発者のGitHubページのREADMEにも記載してあります。
GitHub: https://github.com/yoshida1126/articles_app

📘 概要


このアプリは、技術記事を投稿・共有するための Web サービス(ポートフォリオサイト)です。


記事作成では、差分ビュー・リアルタイムプレビュー・オートセーブ・不要画像の自動削除など、 執筆体験をスムーズにするための機能を多数実装しています。


一方で、記事の投稿やコメント、いいね、フォローに加えて、 ユーザー同士が「どんな記事を保存しているか」を共有し合えるお気に入りリスト機能を実装。


さらに、他ユーザーが作成したリストをブックマークできるなど、 学びが人を通じて広がる“コミュニティ性”も大切にしています。


記事を書く体験と、技術のつながりが自然に生まれる体験の両方を提供する、 「書きやすさ」と「交流」を両立した技術記事プラットフォームを目指して開発しました。


レスポンシブ対応しているのでスマホからでもご覧いただけます。


🔥 特に注力したポイント


  • 画像ファイルの管理における工夫

    • 記事の作成・更新時に使用される画像だけを適切に保存し、不要な画像ファイルは削除されるような仕組みを実装しました。
    • 一部、即時処理できない画像の削除に関しては、Sidekiq を用いたバックグラウンドジョブで非同期的に処理されるようにしています。

  • Fat Controller を避けるための設計

    • 上記のような複雑なビジネスロジックはコントローラに直接書かず、サービスクラスやモジュールに分離 することで、コードの可読性と保守性を高めています。

  • テストのしやすさを意識した設計(DIの導入)

    • モジュール内のメソッドでは Proc を引数として受け取る形にし、依存性注入(DI)を導入
    • これにより、ユニットテストではモックを使用して処理の責務に限定したテストが可能となり、テスト容易性と柔軟性を両立しています。

💡 UI/UX面での工夫


  • 記事作成時の リアルタイムプレビュー を実装し、 Markdown記法を確認しながら編集できるようにしました。

  • 記事編集時の 差分ビュー を実装しました。(jsdiff 使用)

  • 画像ファイルサイズ制限について、 数値での残量表示に加えて「色付きファイルサイズバー」を導入し、 残容量を視覚的に把握しやすくしました。

  • 記事・コメント入力時に リアルタイム文字数カウント を色付きで表示し、 制限文字数を一目で把握できるようにしました。

  • プロフィール画像のトリミング機能 を導入し、 ユーザーが画像の表示範囲を自由に調整できるようにしました。

  • 「見た目の良さ」だけでなく、 使いやすさ・迷わず操作できる導線 を意識し、 開発者自身が使っても快適だと思えるUI/UXを追求しました。

使用技術

💻 開発環境 / バックエンド

  • Ruby 3.2.2
  • Ruby on Rails 7.0.4.3
  • MySQL 8.1.0
  • Nginx
  • Unicorn
  • Redis
  • Sidekiq

🧪 テスト・静的解析

  • RSpec
  • Rubocop

🐳 開発環境構築・CI/CD

  • Docker / Docker Compose
  • CircleCI

☁️ インフラ・クラウドサービス(AWS)


  • AWS
    • VPC
    • EC2
    • Route 53 (現在はコストを抑えるため、Cloudflareに移行しています)
    • S3

🖼️ インフラ構成図 / データモデル(ER図)


インフラ構成図


使用させて頂いたアイコンの各種リンク


CircleCI: https://icons8.com/icon/ep4D1m8k13qZ/circleci

Cloudflare: https://lobehub.com/ja/icons/cloudflare

Docker: https://www.docker.com/ja-jp/company/newsroom/media-resources/

GitHub: https://icons8.com/icon/12599/github

Nginx: https://icons8.com/icon/LhQ8M0RI4YLP/nginx

Ruby on Rails: https://icons8.com/icon/12eMo7h5rCTp/ruby-on-rails

ER図


⚙️ 機能一覧

  • お気に入り記事のリスト機能

    • 気になる記事を自分の「お気に入りリスト」に保存して管理できます。
    • 特徴的なのは、他ユーザーのリストも閲覧可能な点で、
      「このユーザーはどんな技術記事を参考にしているのか?」を知ることができ、
      知識の共有やインスピレーションの広がりを促す設計になっています。

  • 他のユーザーが作成したリストのブックマーク機能

    • 他のユーザーが作成したリストをブックマークして自分のプロフィールからアクセスしやすくしました。これにより、より一層、学びが人から人へと広がる仕組みを提供できるようにしています。

  • ユーザー登録・ログイン機能(devise)

    • 簡単で安全なユーザー認証を実装。

  • 投稿機能

    • 記事の投稿・編集機能を実装。現在は基本的なCRUD操作に加えて、下書き保存機能をサポートしており、ユーザーは編集途中の記事を下書きとして保存できます。また、非同期での自動保存(オートセーブ)に対応しており、編集中の体験をさらに快適にしています。

  • 画像投稿機能

    • プロフィール画像、記事のヘッダー画像、記事本文に貼る画像を投稿可能。
    • 記事本文に貼る画像はダイレクトアップロードリアルタイムプレビューに対応。
    • 記事本文画像の管理における工夫
      • アップロード後、記事のオートセーブで画像を即時アタッチ。
      • 記事送信時に、本文中の画像URLから signed_id を抽出し、未使用画像を自動判別して削除。
      • これにより、不要な画像ファイルがストレージに残らないようにしています。

  • いいね機能

    • 記事への「いいね」機能を実装。今後、ユーザーごとの「いいね」履歴を表示する機能を追加して、ユーザーが過去に参考にした記事を振り返りやすくする予定です。

  • 検索機能(ransack)

    • 検索には Ransack を使用しています。
    • キーワード検索に加えて、記事・ユーザー・リストなど複数の条件による絞り込み検索に対応しています。
    • 今後は、検索条件の拡張や UI の改善など、より使いやすい検索機能を目指してアップデートを行っていく予定です。

  • ハッシュタグ機能(acts-as-taggable-on)

    • 記事にタグを追加して、関連性の高い記事を簡単に見つけられるようにしました。

  • アクセス制限・スパム対策

    Redis を利用し、以下のようなスパム・イタズラ防止のためのアクセス制限機能を実装しています。


    • リクエスト制限:IPごとに 1分間に200リクエストを超えると 429 エラーを返します。

    • 画像:1日あたり合計 10MB までアップロード可能。(プロフィール画像を除く)

    • プロフィール画像の変更 : 1日あたり 5 回まで。

    • 同じ記事やコメントへのいいね・取り消し操作:同一対象への連続操作は 3 秒に 1 回まで制限されます。

🧪 テスト


  • 使用ツール

    • RSpec(テストフレームワーク)
    • Capybara(システムテスト)
    • FactoryBot / Faker(テストデータ生成)

  • 実施しているテストの種類


    • モデルの単体テスト
      • バリデーションや関連付けの確認など、基本的なデータ整合性を担保するテストを記述。

    • システムテスト
      • ユーザーの一連の操作をブラウザ上で再現し、フロー全体の動作を確認。 (主にJavaScriptを使用している箇所をテスト)

    • サービス層・モジュールの単体テスト
      • 複雑なビジネスロジックはサービスクラス・モジュールに切り出し、それぞれに対して責務を限定したユニットテストを実施。

      • 特にモジュールでは Proc を用いた 依存性注入(DI) を行い、テスト時にはモックを使用することで外部依存を排除。柔軟性・保守性・テスト容易性の向上を意識しています。

    • ビューやシステムテストを重視していましたが、最近はユニットテスト(モデル・サービス層)の重要性を認識し、責務を明確にした設計+テストにシフトしています。