Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 17 additions & 1 deletion app/controllers/practices/reports_controller.rb
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,22 @@
class Practices::ReportsController < ApplicationController
def index
@practice = Practice.find(params[:practice_id])
@reports = @practice.reports.list.page(params[:page])
@include_source = include_source?
@reports =
if @include_source
Report.for_practice_including_source(@practice)
else
@practice.reports
end
@reports = @reports.list.page(params[:page])
end

private

def include_source?
# 給付金コースの場合、include_sourceはデフォルトでtrue
return false unless @practice.grant_course?

params.fetch(:include_source, 'true') == 'true'
end
end
6 changes: 4 additions & 2 deletions app/helpers/page_tabs/practices_helper.rb
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,12 @@

module PageTabs
module PracticesHelper
def practice_page_tabs(practice, active_tab:)
def practice_page_tabs(practice, active_tab:, include_source: nil)
# include_source未指定(nil)時は、給付金コースならtrue
include_source = practice.grant_course? if include_source.nil?
tabs = []
tabs << { name: 'プラクティス', link: practice_path(practice) }
tabs << { name: '日報', link: practice_reports_path(practice), count: practice.reports.length }
tabs << { name: '日報', link: practice_reports_path(practice), count: practice.reports_count(include_source:) }
tabs << { name: '質問', link: practice_questions_path(practice), count: practice.questions.length }
tabs << { name: 'Docs', link: practice_pages_path(practice), count: practice.pages.length }
tabs << { name: '動画', link: practice_movies_path(practice), count: practice.movies.length } if movie_available?
Expand Down
11 changes: 11 additions & 0 deletions app/models/practice.rb
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,17 @@ def include_must_read_books?
practices_books.any?(&:must_read)
end

def grant_course?
source_id.present?
end

def reports_count(include_source: nil)
return reports.count unless include_source

ids = [id, source_id].compact
Report.joins(:practices).where(practices: { id: ids }).distinct.count
end

private

def total_learning_minute(report)
Expand Down
5 changes: 5 additions & 0 deletions app/models/report.rb
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ class Report < ApplicationRecord # rubocop:todo Metrics/ClassLength

scope :user, ->(user) { where(user_id: user.id) }

scope :for_practice_including_source, lambda { |practice|
ids = [practice.id, practice.source_id].compact
joins(:practices).where(practices: { id: ids }).distinct
}

def self.ransackable_attributes(_auth_object = nil)
%w[title description reported_on emotion wip created_at updated_at user_id]
end
Expand Down
14 changes: 13 additions & 1 deletion app/views/practices/reports/index.html.slim
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,19 @@
category: category,
practice: @practice

= practice_page_tabs(@practice, active_tab: '日報')
= practice_page_tabs(@practice, active_tab: '日報', include_source: @include_source)

- if @practice.grant_course?
nav.pill-nav
ul.pill-nav__items
li.pill-nav__item
= link_to '全て',
practice_reports_path(@practice, include_source: true),
class: ['pill-nav__item-link', ('is-active' if @include_source)]
li.pill-nav__item
= link_to '給付金コース',
practice_reports_path(@practice, include_source: false),
class: ['pill-nav__item-link', ('is-active' if !@include_source)]

.page-body
.container.is-md
Expand Down
5 changes: 5 additions & 0 deletions db/fixtures/categories.yml
Original file line number Diff line number Diff line change
Expand Up @@ -112,3 +112,8 @@ category23:
name: "Ruby on Rails(Rails 6.1版)"
slug: "ruby-on-rails"
description: "まずはここからはじめましょう。ここでの学習の進め方を学びます。"

category24:
name: "Mac OS X(Reスキル)"
slug: "mac-os-x-reskill"
description: "Railsコースのカテゴリをコピーしたカテゴリです。"
10 changes: 10 additions & 0 deletions db/fixtures/categories_practices.yml
Original file line number Diff line number Diff line change
Expand Up @@ -356,3 +356,13 @@ categories_practice66_2:
practice: practice66
category: category22
position: 3

categories_practice67:
practice: practice113
category: category24
position: 1

categories_practice68:
practice: practice114
category: category24
position: 2
5 changes: 5 additions & 0 deletions db/fixtures/courses_categories.yml
Original file line number Diff line number Diff line change
Expand Up @@ -222,3 +222,8 @@ courses_category45:
course: course5
category: category23
position: 18

courses_category46:
course: course5
category: category24
position: 19
5 changes: 5 additions & 0 deletions db/fixtures/discord_profiles.yml
Original file line number Diff line number Diff line change
Expand Up @@ -335,3 +335,8 @@ discord_profile_new-mentor:
user: new-mentor
account_name: new-mentor
times_url:

discord_profile_grant-course:
user: grant-course
account_name: grant-course
times_url:
12 changes: 12 additions & 0 deletions db/fixtures/practices.yml
Original file line number Diff line number Diff line change
Expand Up @@ -764,3 +764,15 @@ practice112:
goal: "goal..."
include_progress: true
memo: "memo for mentors..."

practice113:
title: "OS X Mountain Lionをクリーンインストールする(Reスキル)"
description: "Railsコースのプラクティスをコピーしたプラクティスです。"
goal: "goal..."
source_id: <%= ActiveRecord::FixtureSet.identify(:practice1) %>

practice114:
title: "Terminalの基礎を覚える(Reスキル)"
description: "Railsコースのプラクティスをコピーしたプラクティスです。"
goal: "goal..."
source_id: <%= ActiveRecord::FixtureSet.identify(:practice2) %>
35 changes: 35 additions & 0 deletions db/fixtures/reports.yml
Original file line number Diff line number Diff line change
Expand Up @@ -505,3 +505,38 @@ report90:
description: |-
たくさんのスタンプがつきました。
reported_on: "2025-10-01 01:00:00"

report91:
user: grant-course
title: 給付金コースのプラクティスの日報
emotion: 2
description: |-
給付金コースのプラクティスの日報です。
practices: practice113
reported_on: "2026-01-01"

report92:
user: komagata
title: Railsコースのコピー元プラクティスの日報
emotion: 2
description: |-
Railsコースのコピー元プラクティスの日報です。
practices: practice1
reported_on: "2026-01-02"

report93:
user: komagata
title: Railsコースのコピー元プラクティス、給付金コースのプラクティスの両方に関連する日報報
emotion: 2
description: |-
Railsコースのコピー元プラクティス、給付金コースのプラクティスの両方に関連する日報報
practices: practice1, practice113
reported_on: "2026-01-03"

report94:
user: komagata
title: プラクティスに関連しない日報
emotion: 2
description: |-
プラクティスに関連しない日報
reported_on: "2026-01-04"
4 changes: 4 additions & 0 deletions db/fixtures/talks.yml
Original file line number Diff line number Diff line change
Expand Up @@ -235,3 +235,7 @@ talk_pjord:
talk_new-mentor:
user: new-mentor
action_completed: true

talk_grant_course:
user: grant-course
action_completed: true
20 changes: 20 additions & 0 deletions db/fixtures/users.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1555,3 +1555,23 @@ new-mentor:
created_at: <%= Time.current %>
sent_student_followup_message: true
last_activity_at: <%= Time.current %>

grant-course:
login_name: grant-course
email: grant-course@fjord.jp
crypted_password: $2a$10$n/xv4/1luueN6plzm2OyDezWlZFyGHjQEf4hwAW1r3k.lCm0frPK. # testtest
salt: zW3kQ9ubsxQQtzzzs4ap
name: 給付金コースのユーザー
name_kana: キュウフキンコースノユーザー
github_account: grant-course
twitter_account: grant-course
facebook_url: https://www.facebook.com/fjordllc/grant-course
blog_url: http://grant-course.org
description: "給付金コースを受講中のユーザーです。"
course: course5
job: office_worker
os: mac
organization: Rails大学
updated_at: "2025-01-01 00:00:00"
created_at: "2025-01-01 00:00:00"
last_activity_at: "2025-01-01 00:00:00"
5 changes: 5 additions & 0 deletions test/fixtures/learning_times.yml
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,8 @@ learning_time8:
report: report10
started_at: 2020-09-10 12:00:00
finished_at: 2020-09-10 13:15:00

learning_time9:
report: report78
started_at: 2026-01-01 00:00:00
finished_at: 2026-01-01 01:00:00
22 changes: 22 additions & 0 deletions test/fixtures/practices.yml
Original file line number Diff line number Diff line change
Expand Up @@ -390,3 +390,25 @@ practice63:
goal: "goal..."
include_progress: true
memo: "memo for mentors..."

practice64:
title: "Railsコースのコピー元プラクティス"
description: "Railsコースのコピー元プラクティスです。"
goal: "goal..."

practice65:
title: "給付金コースのプラクティス"
description: "給付金コースのプラクティスです。"
goal: "goal..."
source_id: <%= ActiveRecord::FixtureSet.identify(:practice64) %>

practice66:
title: "日報が存在しないRailsコースのコピー元プラクティス"
description: "日報が存在しないRailsコースのコピー元プラクティスです。"
goal: "goal..."

practice67:
title: "日報が存在しない給付金コースのプラクティス"
description: "日報が存在しない給付金コースのプラクティスです。"
goal: "goal..."
source_id: <%= ActiveRecord::FixtureSet.identify(:practice66) %>
39 changes: 39 additions & 0 deletions test/fixtures/reports.yml
Original file line number Diff line number Diff line change
Expand Up @@ -358,3 +358,42 @@ report75:
description: WIPです
wip: true
reported_on: "2022-04-02"

report76:
user: komagata
title: "Railsコースのコピー元プラクティスの日報"
emotion: 1
description: Railsコースのコピー元プラクティスの日報です。
practices: practice64
reported_on: "2026-01-01"

report77:
user: komagata
title: "給付金コースのプラクティスの日報"
emotion: 1
description: 給付金コースのプラクティスの日報です。
practices: practice65
reported_on: "2026-01-02"

report78:
user: komagata
title: "Railsコースのコピー元プラクティス、給付金コースのプラクティスの両方に関連する日報"
emotion: 1
description: Railsコースのコピー元プラクティス、給付金コースのプラクティスの両方に関連する日報です。
practices: practice64, practice65
reported_on: "2026-01-03"

report79:
user: komagata
title: "給付金コースではないプラクティスの日報"
emotion: 1
description: 給付金コースではないプラクティスの日報です。
practices: practice1
reported_on: "2026-01-04"

report80:
user: komagata
title: "プラクティスに関連しない日報"
emotion: 1
description: プラクティスに関連しない日報です。
reported_on: "2026-01-05"
2 changes: 1 addition & 1 deletion test/integration/api/reports/unchecked_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,6 @@ class API::Reports::UncheckedTest < ActionDispatch::IntegrationTest
get counts_api_reports_unchecked_index_path(format: :text),
headers: { 'Authorization' => "Bearer #{token}" }
assert_response :ok
assert_match '65件', response.body
assert_match '70件', response.body
end
end
58 changes: 58 additions & 0 deletions test/models/practice_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -87,4 +87,62 @@ class PracticeTest < ActiveSupport::TestCase
practice.update!(source_id: 99_999)
end
end

test '#grant_course? returns true when practice has source' do
assert Practice.new(source_id: 1).grant_course?
assert_not Practice.new(source_id: nil).grant_course?
end

test '#reports_count sums reports of self and source when include_source is true' do
source = practices(:practice66)
practice = practices(:practice67)

assert_equal 0, practice.reports_count(include_source: true)
Report.create!(
user: users(:komagata),
title: '日報が存在しないRailsコースのコピー元プラクティスの日報',
description: '日報が存在しないRailsコースのコピー元プラクティスの日報です。',
practices: [source],
reported_on: Time.zone.today
)
Report.create!(
user: users(:komagata),
title: '日報が存在しない給付金コースのプラクティスの日報',
description: '日報が存在しない給付金コースのプラクティスの日報です。',
practices: [practice],
reported_on: Time.zone.today - 1
)

assert_equal 2, practice.reports_count(include_source: true)
end

test '#reports_count counts only self reports when include_source is false' do
practice = practices(:practice66)

assert_equal 0, practice.reports_count(include_source: false)
Report.create!(
user: users(:komagata),
title: '日報が存在しないRailsコースのコピー元プラクティスの日報',
description: '日報が存在しないRailsコースのコピー元プラクティスの日報です。',
practices: [practice],
reported_on: Time.zone.today
)

assert_equal 1, practice.reports_count(include_source: false)
end

test '#reports_count does not double count reports when associated with both source and practice' do
source = practices(:practice66)
practice = practices(:practice67)
Report.create!(
user: users(:komagata),
title: '日報が存在しないRailsコースのコピー元プラクティス、日報が存在しない給付金コースのプラクティスの両方に関連する日報',
description: '日報が存在しないRailsコースのプラクティス、日報が存在しない給付金コースのプラクティスの両方に関連する日報です。',
practices: [source, practice],
reported_on: Time.zone.today
)

assert_equal 1, practice.reports_count(include_source: false)
assert_equal 1, practice.reports_count(include_source: true)
end
end
16 changes: 16 additions & 0 deletions test/models/report_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -73,4 +73,20 @@ class ReportTest < ActiveSupport::TestCase
assert_empty unchecked_report.checks
assert_includes Report.unchecked, unchecked_report
end

test '.for_practice_including_source returns practice and source reports' do
practice = practices(:practice65)
practice_report = reports(:report77)
source_report = reports(:report76)
practice_and_source_report = reports(:report78)
other_report = reports(:report79)
unrelated_report = reports(:report80)
result = Report.for_practice_including_source(practice)

assert_includes result, practice_report
assert_includes result, source_report
assert_includes result, practice_and_source_report
assert_not_includes result, other_report
assert_not_includes result, unrelated_report
end
end
Loading
Loading