Add relation between Goal and LocalTarget
This is similar to what we do with investments, which belong to a heading but also belong to a budget. In our case, the reason is we've been asked to add local targets which belong to a goal but are not related to any existing target. Even though we're not implementing that case right now, we're adding the relation so we don't have to add data migrations in the future.
This commit is contained in:
@@ -4,6 +4,7 @@ class SDG::Goal < ApplicationRecord
|
||||
validates :code, presence: true, uniqueness: true, inclusion: { in: 1..17 }
|
||||
|
||||
has_many :targets, dependent: :destroy
|
||||
has_many :local_targets, dependent: :destroy
|
||||
|
||||
def title
|
||||
I18n.t("sdg.goals.goal_#{code}.title")
|
||||
|
||||
@@ -2,8 +2,6 @@ class SDG::LocalTarget < ApplicationRecord
|
||||
include Comparable
|
||||
include SDG::Related
|
||||
|
||||
delegate :goal, to: :target
|
||||
|
||||
translates :title, touch: true
|
||||
translates :description, touch: true
|
||||
include Globalizable
|
||||
@@ -14,8 +12,12 @@ class SDG::LocalTarget < ApplicationRecord
|
||||
validates :code, presence: true, uniqueness: true,
|
||||
format: ->(local_target) { /\A#{local_target.target&.code}\.\d+/ }
|
||||
validates :target, presence: true
|
||||
validates :goal, presence: true
|
||||
|
||||
belongs_to :target
|
||||
belongs_to :goal
|
||||
|
||||
before_validation :set_related_goal
|
||||
|
||||
def self.[](code)
|
||||
find_by!(code: code)
|
||||
@@ -40,4 +42,8 @@ class SDG::LocalTarget < ApplicationRecord
|
||||
def subcode
|
||||
code.split(".").last
|
||||
end
|
||||
|
||||
def set_related_goal
|
||||
self.goal ||= target&.goal
|
||||
end
|
||||
end
|
||||
|
||||
5
db/migrate/20210123100638_add_goals_to_local_targets.rb
Normal file
5
db/migrate/20210123100638_add_goals_to_local_targets.rb
Normal file
@@ -0,0 +1,5 @@
|
||||
class AddGoalsToLocalTargets < ActiveRecord::Migration[5.2]
|
||||
def change
|
||||
add_reference :sdg_local_targets, :goal
|
||||
end
|
||||
end
|
||||
@@ -10,7 +10,7 @@
|
||||
#
|
||||
# It's strongly recommended that you check this file into your version control system.
|
||||
|
||||
ActiveRecord::Schema.define(version: 2021_01_07_125458) do
|
||||
ActiveRecord::Schema.define(version: 2021_01_23_100638) do
|
||||
|
||||
# These are extensions that must be enabled in order to support this database
|
||||
enable_extension "pg_trgm"
|
||||
@@ -1322,7 +1322,9 @@ ActiveRecord::Schema.define(version: 2021_01_07_125458) do
|
||||
t.string "code"
|
||||
t.datetime "created_at", null: false
|
||||
t.datetime "updated_at", null: false
|
||||
t.bigint "goal_id"
|
||||
t.index ["code"], name: "index_sdg_local_targets_on_code", unique: true
|
||||
t.index ["goal_id"], name: "index_sdg_local_targets_on_goal_id"
|
||||
t.index ["target_id"], name: "index_sdg_local_targets_on_target_id"
|
||||
end
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ FactoryBot.define do
|
||||
sequence(:description) { |n| "Help for Local Target #{n}" }
|
||||
|
||||
target { SDG::Target[code.rpartition(".").first] }
|
||||
goal { SDG::Goal[code.split(".")[0]] }
|
||||
end
|
||||
|
||||
factory :sdg_phase, class: "SDG::Phase" do
|
||||
|
||||
@@ -18,7 +18,7 @@ describe SDG::LocalTarget do
|
||||
end
|
||||
|
||||
it "is not valid without a code" do
|
||||
expect(build(:sdg_local_target, code: nil, target: SDG::Target[1.1])).not_to be_valid
|
||||
expect(build(:sdg_local_target, code: nil, target: SDG::Target[1.1], goal: SDG::Goal[1])).not_to be_valid
|
||||
end
|
||||
|
||||
it "is not valid when code does not include associated target code" do
|
||||
@@ -47,6 +47,15 @@ describe SDG::LocalTarget do
|
||||
expect(build(:sdg_local_target, target: nil)).not_to be_valid
|
||||
end
|
||||
|
||||
describe "#set_related_goal" do
|
||||
it "before validation set related goal" do
|
||||
local_target = build(:sdg_local_target, code: "1.1.1", target: SDG::Target["1.1"], goal: nil)
|
||||
|
||||
expect(local_target).to be_valid
|
||||
expect(local_target.goal).to eq(SDG::Goal[1])
|
||||
end
|
||||
end
|
||||
|
||||
describe "#goal" do
|
||||
it "returns the target goal" do
|
||||
local_target = create(:sdg_local_target, code: "1.1.1")
|
||||
|
||||
Reference in New Issue
Block a user