Class: PlanMyStuff::Link
- Inherits:
-
Object
- Object
- PlanMyStuff::Link
- Includes:
- ActiveModel::Attributes, ActiveModel::Model, ActiveModel::Serializers::JSON
- Defined in:
- lib/plan_my_stuff/link.rb
Overview
Value object representing a typed relationship between two issues. Built by Issue#add_related!, #add_blocker!, #add_sub_issue!, #set_parent!, and #mark_duplicate!; also returned from their remove_* counterparts so callers can render activity-log lines like “Added parent issue: owner/repo#42”.
Metadata-backed types live in IssueMetadata#links; native types are routed through GitHub APIs and never persisted in our metadata.
Constant Summary collapse
- METADATA_TYPES =
%w[related].freeze
- NATIVE_TYPES =
%w[blocking blocked_by parent sub_ticket duplicate_of].freeze
- ALL_TYPES =
(METADATA_TYPES + NATIVE_TYPES).freeze
Class Method Summary collapse
-
.build(input, type: nil, source_repo: nil) ⇒ PlanMyStuff::Link
Builds and validates a
Linkfrom anIssue-like object, anotherLink, or a hash.
Instance Method Summary collapse
- #==(other) ⇒ Boolean (also: #eql?)
- #hash ⇒ Integer
-
#issue ⇒ PlanMyStuff::Issue
Lazy-fetches and memoizes the target
Issue. -
#issue_number ⇒ Integer
Target issue’s GitHub issue number.
-
#repo ⇒ String
Full “owner/name” path of the target issue’s repo.
- #same_repo?(other_repo) ⇒ Boolean
- #to_h ⇒ Hash
-
#to_s ⇒ String
E.g.
-
#type ⇒ String
One of ALL_TYPES.
Class Method Details
.build(input, type: nil, source_repo: nil) ⇒ PlanMyStuff::Link
Builds and validates a Link from an Issue-like object, another Link, or a hash. type: fills in when the input does not carry one; source_repo fills in when the hash input does not carry one. Raises ActiveModel::ValidationError on missing/invalid fields, ArgumentError when input is an unsupported shape.
47 48 49 50 51 52 53 54 55 56 57 58 59 |
# File 'lib/plan_my_stuff/link.rb', line 47 def build(input, type: nil, source_repo: nil) return input if input.is_a?(PlanMyStuff::Link) link = if input.is_a?(Hash) build_from_hash(input, type: type, source_repo: source_repo) else build_from_issue_like(input, type: type) end link.validate! link end |
Instance Method Details
#==(other) ⇒ Boolean Also known as: eql?
131 132 133 134 135 |
# File 'lib/plan_my_stuff/link.rb', line 131 def ==(other) return false unless other.is_a?(PlanMyStuff::Link) type == other.type && issue_number == other.issue_number && repo == other.repo end |
#hash ⇒ Integer
140 141 142 |
# File 'lib/plan_my_stuff/link.rb', line 140 def hash [type, issue_number, repo].hash end |
#issue ⇒ PlanMyStuff::Issue
Lazy-fetches and memoizes the target Issue.
123 124 125 |
# File 'lib/plan_my_stuff/link.rb', line 123 def issue @issue ||= PlanMyStuff::Issue.find(issue_number, repo: repo) end |
#issue_number ⇒ Integer
Returns target issue’s GitHub issue number.
26 |
# File 'lib/plan_my_stuff/link.rb', line 26 attribute :issue_number, :integer |
#repo ⇒ String
Returns full “owner/name” path of the target issue’s repo.
28 |
# File 'lib/plan_my_stuff/link.rb', line 28 attribute :repo, :string |
#same_repo?(other_repo) ⇒ Boolean
113 114 115 116 117 |
# File 'lib/plan_my_stuff/link.rb', line 113 def same_repo?(other_repo) return false if other_repo.nil? repo == self.class.__send__(:repo_string, other_repo) end |
#to_h ⇒ Hash
101 102 103 104 105 106 107 |
# File 'lib/plan_my_stuff/link.rb', line 101 def to_h { type: type, issue_number: issue_number, repo: repo, } end |
#to_s ⇒ String
Returns e.g. “owner/repo#42”.
96 97 98 |
# File 'lib/plan_my_stuff/link.rb', line 96 def to_s "#{repo}##{issue_number}" end |
#type ⇒ String
Returns one of ALL_TYPES.
24 |
# File 'lib/plan_my_stuff/link.rb', line 24 attribute :type, :string |