From ce0ae8471044b0728af92881f4b7df1b6ecd84cd Mon Sep 17 00:00:00 2001 From: momo3404 Date: Thu, 29 Jan 2026 14:42:30 -0700 Subject: [PATCH 1/8] Update `plans_controller` to include complete plan flag - This optional parameter will return all questions and answers in a plan when set to true --- app/controllers/api/v2/plans_controller.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/controllers/api/v2/plans_controller.rb b/app/controllers/api/v2/plans_controller.rb index 7714e9c892..77d209a2c6 100644 --- a/app/controllers/api/v2/plans_controller.rb +++ b/app/controllers/api/v2/plans_controller.rb @@ -4,6 +4,7 @@ module Api module V2 class PlansController < BaseApiController # rubocop:todo Style/Documentation respond_to :json + before_action :set_complete_param, only: %i[show index] # GET /api/v2/plans/:id def show @@ -28,6 +29,10 @@ def index @items = paginate_response(results: @plans) render '/api/v2/plans/index', status: :ok end + + def set_complete_param + @complete = params[:complete].to_s.downcase == 'true' + end end end end From 7ca5d12c60458aa0457b01ae7fc2aa83d57a27cb Mon Sep 17 00:00:00 2001 From: momo3404 Date: Thu, 29 Jan 2026 14:44:30 -0700 Subject: [PATCH 2/8] Update `plan_presenter` to include complete plan flag - Add the fetch_all_q_and_a function to return all questions and answers belonging to a plan to allow flag to work - Add complete_plan_data to call fetch function inside initialize --- app/presenters/api/v2/plan_presenter.rb | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/app/presenters/api/v2/plan_presenter.rb b/app/presenters/api/v2/plan_presenter.rb index 204cd68011..aa248b1993 100644 --- a/app/presenters/api/v2/plan_presenter.rb +++ b/app/presenters/api/v2/plan_presenter.rb @@ -4,9 +4,9 @@ module Api module V2 # Helper class for the API V2 project / DMP class PlanPresenter - attr_reader :data_contact, :contributors, :costs + attr_reader :data_contact, :contributors, :costs, :complete_plan_data - def initialize(plan:) + def initialize(plan:, complete: false) @contributors = [] return unless plan.present? @@ -22,6 +22,8 @@ def initialize(plan:) end @costs = plan_costs(plan: @plan) + + @complete_plan_data = fetch_all_q_and_a if complete end # Extract the ARK or DOI for the DMP OR use its URL if none exists @@ -54,6 +56,22 @@ def plan_costs(plan:) currency_code: 'usd', value: answer.text } end end + + # Fetch all questions and answers from a plan, regardless of theme + def fetch_all_q_and_a + return [] unless @plan.questions.present? + + @plan.questions.filter_map do |q| + a = @plan.answers.find { |ans| ans.question_id == q.id } + next unless a.present? + + { + title: "Question #{q.number || q.id}", + question: q.text.to_s, + answer: a.text.to_s + } + end + end end end end From 245d11cd65c98d1b174a4def896393506a15201a Mon Sep 17 00:00:00 2001 From: momo3404 Date: Thu, 29 Jan 2026 14:45:27 -0700 Subject: [PATCH 3/8] Update `plans/_show,json.jbuilder` to work with complete plan flag - Add call for complete flag - Add questions and answers of a plan to the json if complete is set to true --- app/views/api/v2/plans/_show.json.jbuilder | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/app/views/api/v2/plans/_show.json.jbuilder b/app/views/api/v2/plans/_show.json.jbuilder index 0de52775a3..3cd5dfe8c3 100644 --- a/app/views/api/v2/plans/_show.json.jbuilder +++ b/app/views/api/v2/plans/_show.json.jbuilder @@ -4,7 +4,7 @@ json.schema 'https://github.com/RDA-DMP-Common/RDA-DMP-Common-Standard/tree/master/examples/JSON/JSON-schema/1.0' -presenter = Api::V2::PlanPresenter.new(plan: plan) +presenter = Api::V2::PlanPresenter.new(plan: plan, complete: @complete) # Note the symbol of the dmproadmap json object # nested in extensions which is the container for the json template object, etc. @@ -68,5 +68,18 @@ unless @minimal json.title template.title end end + + if @complete + json.complete_plan do + q_and_a = presenter.complete_plan_data + next if q_and_a.blank? + + json.array! q_and_a do |item| + json.title item[:title] + json.question item[:question] + json.answer item[:answer] + end + end + end end end From 6f7ba846bb24ed9cdd69a9740d4199a53afe2c4f Mon Sep 17 00:00:00 2001 From: momo3404 Date: Thu, 29 Jan 2026 14:42:30 -0700 Subject: [PATCH 4/8] Update `plans_controller` to include complete plan flag - This optional parameter will return all questions and answers in a plan when set to true --- app/controllers/api/v2/plans_controller.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/app/controllers/api/v2/plans_controller.rb b/app/controllers/api/v2/plans_controller.rb index 7714e9c892..77d209a2c6 100644 --- a/app/controllers/api/v2/plans_controller.rb +++ b/app/controllers/api/v2/plans_controller.rb @@ -4,6 +4,7 @@ module Api module V2 class PlansController < BaseApiController # rubocop:todo Style/Documentation respond_to :json + before_action :set_complete_param, only: %i[show index] # GET /api/v2/plans/:id def show @@ -28,6 +29,10 @@ def index @items = paginate_response(results: @plans) render '/api/v2/plans/index', status: :ok end + + def set_complete_param + @complete = params[:complete].to_s.downcase == 'true' + end end end end From 0ff52ebc1bb592c34af6eece54647a2126b587ca Mon Sep 17 00:00:00 2001 From: momo3404 Date: Thu, 29 Jan 2026 14:44:30 -0700 Subject: [PATCH 5/8] Update `plan_presenter` to include complete plan flag - Add the fetch_all_q_and_a function to return all questions and answers belonging to a plan to allow flag to work - Add complete_plan_data to call fetch function inside initialize --- app/presenters/api/v2/plan_presenter.rb | 22 ++++++++++++++++++++-- 1 file changed, 20 insertions(+), 2 deletions(-) diff --git a/app/presenters/api/v2/plan_presenter.rb b/app/presenters/api/v2/plan_presenter.rb index c841844c6c..0b0da62d8a 100644 --- a/app/presenters/api/v2/plan_presenter.rb +++ b/app/presenters/api/v2/plan_presenter.rb @@ -4,9 +4,9 @@ module Api module V2 # Helper class for the API V2 project / DMP class PlanPresenter - attr_reader :data_contact, :contributors, :costs + attr_reader :data_contact, :contributors, :costs, :complete_plan_data - def initialize(plan:) + def initialize(plan:, complete: false) @contributors = [] return unless plan.present? @@ -22,6 +22,8 @@ def initialize(plan:) end @costs = plan_costs(plan: @plan) + + @complete_plan_data = fetch_all_q_and_a if complete end # Extract the ARK or DOI for the DMP OR use its URL if none exists @@ -55,6 +57,22 @@ def plan_costs(plan:) currency_code: 'usd', value: answer.text } end end + + # Fetch all questions and answers from a plan, regardless of theme + def fetch_all_q_and_a + return [] unless @plan.questions.present? + + @plan.questions.filter_map do |q| + a = @plan.answers.find { |ans| ans.question_id == q.id } + next unless a.present? + + { + title: "Question #{q.number || q.id}", + question: q.text.to_s, + answer: a.text.to_s + } + end + end end end end From 7bf6d95a87c80f2463053f3f6fdd341fa21a99a6 Mon Sep 17 00:00:00 2001 From: momo3404 Date: Thu, 29 Jan 2026 14:45:27 -0700 Subject: [PATCH 6/8] Update `plans/_show,json.jbuilder` to work with complete plan flag - Add call for complete flag - Add questions and answers of a plan to the json if complete is set to true --- app/views/api/v2/plans/_show.json.jbuilder | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/app/views/api/v2/plans/_show.json.jbuilder b/app/views/api/v2/plans/_show.json.jbuilder index 0de52775a3..3cd5dfe8c3 100644 --- a/app/views/api/v2/plans/_show.json.jbuilder +++ b/app/views/api/v2/plans/_show.json.jbuilder @@ -4,7 +4,7 @@ json.schema 'https://github.com/RDA-DMP-Common/RDA-DMP-Common-Standard/tree/master/examples/JSON/JSON-schema/1.0' -presenter = Api::V2::PlanPresenter.new(plan: plan) +presenter = Api::V2::PlanPresenter.new(plan: plan, complete: @complete) # Note the symbol of the dmproadmap json object # nested in extensions which is the container for the json template object, etc. @@ -68,5 +68,18 @@ unless @minimal json.title template.title end end + + if @complete + json.complete_plan do + q_and_a = presenter.complete_plan_data + next if q_and_a.blank? + + json.array! q_and_a do |item| + json.title item[:title] + json.question item[:question] + json.answer item[:answer] + end + end + end end end From e4e472d36450b892c0219a9e6302f283202cbdd4 Mon Sep 17 00:00:00 2001 From: momo3404 Date: Fri, 30 Jan 2026 15:12:36 -0700 Subject: [PATCH 7/8] Fix eager loading in questions and answers --- app/controllers/api/v2/plans_controller.rb | 2 +- app/presenters/api/v2/plan_presenter.rb | 11 ++++++----- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/app/controllers/api/v2/plans_controller.rb b/app/controllers/api/v2/plans_controller.rb index 77d209a2c6..61e8e01db4 100644 --- a/app/controllers/api/v2/plans_controller.rb +++ b/app/controllers/api/v2/plans_controller.rb @@ -10,7 +10,7 @@ class PlansController < BaseApiController # rubocop:todo Style/Documentation def show raise Pundit::NotAuthorizedError unless @scopes.include?('read') - @plan = Plan.find_by(id: params[:id]) + @plan = Plan.includes(roles: :user).find(params[:id]) raise Pundit::NotAuthorizedError unless @plan.present? diff --git a/app/presenters/api/v2/plan_presenter.rb b/app/presenters/api/v2/plan_presenter.rb index 0b0da62d8a..ec494558f7 100644 --- a/app/presenters/api/v2/plan_presenter.rb +++ b/app/presenters/api/v2/plan_presenter.rb @@ -60,16 +60,17 @@ def plan_costs(plan:) # Fetch all questions and answers from a plan, regardless of theme def fetch_all_q_and_a - return [] unless @plan.questions.present? + answers = @plan.answers.includes(:question) + return [] unless answers.present? - @plan.questions.filter_map do |q| - a = @plan.answers.find { |ans| ans.question_id == q.id } - next unless a.present? + answers.filter_map do |answer| + q = answer.question + next unless q.present? { title: "Question #{q.number || q.id}", question: q.text.to_s, - answer: a.text.to_s + answer: answer.text.to_s } end end From acd01c0812f5738ccb394174a81529498bdb778e Mon Sep 17 00:00:00 2001 From: momo3404 Date: Mon, 2 Feb 2026 13:53:45 -0700 Subject: [PATCH 8/8] Bring find_by back --- app/controllers/api/v2/plans_controller.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/controllers/api/v2/plans_controller.rb b/app/controllers/api/v2/plans_controller.rb index 61e8e01db4..df89d72124 100644 --- a/app/controllers/api/v2/plans_controller.rb +++ b/app/controllers/api/v2/plans_controller.rb @@ -10,7 +10,7 @@ class PlansController < BaseApiController # rubocop:todo Style/Documentation def show raise Pundit::NotAuthorizedError unless @scopes.include?('read') - @plan = Plan.includes(roles: :user).find(params[:id]) + @plan = Plan.includes(roles: :user).find_by(id: params[:id]) raise Pundit::NotAuthorizedError unless @plan.present?