18
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Ruby モデルを作ろう:User と Post を使ったクラス設計ハンズオン

Last updated at Posted at 2025-03-28

はじめに

このハンズオンでは、Ruby を使って UserPost という2つのクラスを題材に、オブジェクト指向の基本設計〜機能拡張まで段階的に学びます。

前提:Ruby が実行できる環境を準備してください。

問題文 (ステップが4つ)

【ステップ 1】 User クラスの作成
【ステップ 2】 Post クラスの作成
【ステップ 3】 User が複数の Post を持てるように
【ステップ 4】 応用

[その他] 拡張アイデア (今回はしない)

  1. Post にカテゴリ・タグを持たせて分類出来るようにする
  2. User に自動採番される ID (通し番) を付与する
  3. Post に "いいね" 機能を追加 (カウントして increment)
  4. Post を CSV に書き出し/読み込みできるようにする
  5. User のデータを JSON で出力できるようにする
  6. Post を作成日付のフィルターで検索できるようにする

ハンズオン

【ステップ 1】 User クラスの作成

【問題】 次の仕様を満たす User クラスを作成してください。

  • ユーザーの名前とメールアドレスを持つ
  • ユーザーの名前を取得できる(name)
  • ユーザーの情報を表示する info メソッドがある
🔧 使用例(この動作になるように作る):
user = User.new("Alice", "alice@example.com")
puts user.name         #=> Alice
puts user.info         #=> 名前: Alice, メール: alice@example.com
答えを見る
class User
  attr_reader :name

  def initialize(name, email)
    @name = name
    @email = email
  end

  def info
    "名前: #{@name}, メール: #{@email}"
  end
end

# 動作確認
user = User.new("Alice", "alice@example.com")
puts user.name         #=> "Alice"
puts user.info         #=> "名前: Alice, メール: alice@example.com"

【ステップ 2】 Post クラスの作成

【問題】 次の仕様を満たす Post クラスを作成してください

  • 投稿のタイトルと本文を持つ
  • 投稿の内容を表示する summary メソッドがある

🔧 使用例(この動作になるように作ってね):

post = Post.new("初投稿", "これは最初の投稿です。")
puts post.summary
#=> タイトル: 初投稿
#   本文: これは最初の投稿です。
答えを見る
class Post
  def initialize(title, body)
    @title = title
    @body = body
  end

  def summary
    "タイトル: #{@title}\n本文: #{@body}"
  end
end

post = Post.new("初投稿", "これは最初の投稿です。")
puts post.summary

【ステップ 3】 User に Post を持たせる

【問題】 User クラスに、複数の投稿(Post)を持たせられるように拡張してください

  • add_post(post) で投稿を追加できる
  • list_posts ですべての投稿のタイトルを表示できる

🔧 使用例(この動作になるように作ってね):

user = User.new("Bob", "bob@example.com")
post1 = Post.new("日記1", "今日は晴れ")
post2 = Post.new("日記2", "今日は雨")

user.add_post(post1)
user.add_post(post2)
user.list_posts
#=> ユーザーBobの投稿一覧:
#   - 日記1
#   - 日記2
答えを見る
class User
  attr_reader :name, :posts

  def initialize(name, email)
    @name = name
    @email = email
    @posts = []
  end

  def info
    "名前: #{@name}, メール: #{@email}"
  end

  def add_post(post)
    @posts << post
  end

  def list_posts
    puts "ユーザー#{@name}の投稿一覧:"
    @posts.each do |post|
      puts "- #{post.title}"
    end
  end
end

class Post
  attr_reader :title

  def initialize(title, body)
    @title = title
    @body = body
  end

  def summary
    "タイトル: #{@title}\n本文: #{@body}"
  end
end

user = User.new("Bob", "bob@example.com")
post1 = Post.new("日記1", "今日は晴れ")
post2 = Post.new("日記2", "今日は雨")

user.add_post(post1)
user.add_post(post2)
user.list_posts
#=> ユーザーBobの投稿一覧:
#   - 日記1
#   - 日記2

【ステップ 4】 応用

以下の機能を追加してください (検索と投稿数の取得はUserクラスに定義)

  • 投稿に created_at を追加して、投稿順(降順)に並べて表示
  • 投稿をキーワードで検索できる機能 (search_posts)
  • User クラスで投稿数を取得(post_count)

🔧 使用例(この動作になるように作ってね):

user = User.new("Bob", "bob@example.com")
post1 = Post.new("日記1", "今日は晴れ")
post2 = Post.new("日記2", "今日は雨")
post3 = Post.new("日記3", "今日は曇り")

user.add_post(post1)
user.add_post(post2)
user.add_post(post3)

user.list_posts
# ユーザーBobの投稿一覧:
# - 日記3
# - 日記2
# - 日記1
p user.search_posts("曇り") # [#<Post:0x0000000100608e60 @title="日記3", @body="今日は曇り", @created_at=2025-03-28 20:08:18.78414 +0900>]
p user.post_count # 3
答えを見る
class User
  attr_reader :name, :posts

  def initialize(name, email)
    @name = name
    @email = email
    @posts = []
  end

  def info
    "名前: #{@name}, メール: #{@email}"
  end

  def add_post(post)
    @posts << post
  end

  def list_posts
    puts "ユーザー#{@name}の投稿一覧:"
    @posts.sort_by{ |post| post.created_at }.reverse.each do |post|
      puts "- #{post.title}"
    end
  end

  def search_posts(keyword)
    @posts.select { |post| post.title.include?(keyword) || post.body.include?(keyword) }
  end

  def post_count
    @posts.length
  end
end

class Post
  attr_reader :title, :body, :created_at

  def initialize(title, body)
    @title = title
    @body = body
    @created_at = Time.now
  end

  def summary
    "タイトル: #{@title}\n本文: #{@body}"
  end
end

user = User.new("Bob", "bob@example.com")
post1 = Post.new("日記1", "今日は晴れ")
post2 = Post.new("日記2", "今日は雨")
post3 = Post.new("日記3", "今日は曇り")

user.add_post(post1)
user.add_post(post2)
user.add_post(post3)

user.list_posts
p user.search_posts("曇り")
p user.post_count

終わりに

普段フレームワークを使って開発しているけれど、「オブジェクト指向を本当に理解できているか不安…」という人におすすめの学習方法です。

AIに「Rubyでオブジェクト指向を学びたいから、UserとPostの関係性でステップごとに問題を作って。ハンズオン形式でやりたい」とお願いすれば、すぐに問題を生成してくれます。

「ステップを5つ用意して」や「いいね機能や投稿の編集・削除のステップを追加して」、「クラス継承のステップもほしい」といった細かい指示を出すと、より実践的で自分に合った問題が作れるのでオススメです。

学習のアイデア出しの段階からAIに相談してみるのもアリですね!

また、株式会社シンシアでは、実務未経験のエンジニアの方や学生エンジニアインターンを採用し一緒に働いています。
※ シンシアにおける働き方の様子はこちら

弊社には年間100人程度の実務未経験の方に応募いただき、技術面接を実施しております。
この記事が少しでも学びになったという方は、ぜひ wantedly のストーリーもご覧いただけるととても嬉しいです!

18
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
18
12

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?