forked from ManageIQ/manageiq
-
Notifications
You must be signed in to change notification settings - Fork 1
/
ar_miq_set.rb
153 lines (122 loc) · 4.27 KB
/
ar_miq_set.rb
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
module ActsAsMiqSetMember
extend ActiveSupport::Concern
included do
MiqSetMembership.send(:belongs_to, miq_set_class.name.underscore.to_sym, :foreign_key => :miq_set_id)
has_many :miq_set_memberships,
:as => :member,
:dependent => :delete_all
has_many :miq_sets,
:class_name => miq_set_class.to_s, # rubocop:disable Rails/ReflectionClassName
:source => miq_set_class.name.underscore.to_sym,
:through => :miq_set_memberships
has_many :memberof,
:class_name => miq_set_class.to_s, # rubocop:disable Rails/ReflectionClassName
:source => miq_set_class.name.underscore.to_sym,
:through => :miq_set_memberships
has_many miq_set_class.name.underscore.pluralize.to_sym,
:class_name => miq_set_class.to_s, # rubocop:disable Rails/ReflectionClassName
:source => miq_set_class.name.underscore.to_sym,
:through => :miq_set_memberships
end
module ClassMethods
def miq_set_class
@miq_set_class ||= "#{name}Set".constantize
end
def sets
miq_set_class.all
end
end # module SingletonMethods
def make_memberof(set)
set.add_member(self)
end
def make_not_memberof(set)
set.remove_member(self)
end
end # module ActsAsMiqSetMember
module ActiveRecord
class Base
def self.acts_as_miq_set_member
include ActsAsMiqSetMember
end
def self.acts_as_miq_set(model_class = nil)
include ActsAsMiqSet
self.model_class = model_class unless model_class.nil?
end
end
end
module ActsAsMiqSet
extend ActiveSupport::Concern
included do
include UuidMixin
self.table_name = "miq_sets"
self.inheritance_column = :set_type
serialize :set_data
validates :name,
:presence => true,
:uniqueness_when_changed => {
:scope => [:set_type, :userid, :group_id],
:if => proc { |c| c.class.in_my_region.exists?(:name => c.name) }
}
validates :description,
:presence => true
belongs_to :owner,
:polymorphic => true
has_many :miq_set_memberships,
:foreign_key => :miq_set_id,
:dependent => :delete_all
acts_as_miq_taggable
[:members, :miq_sets, :children, model_table_name.to_sym].each do |hm_relation|
has_many hm_relation,
:through => :miq_set_memberships,
:source => :member,
:source_type => model_class.name.to_s
end
end
module ClassMethods
# HACK: We need to do this to fake AR into doing STI so that polymorphic relationships to
# this class save the *_type column with the full sub-class's name as opposed to the
# base model class. This is needed so that tagging works properly. Once tagging is reworked
# to handle the base model class name this can be removed and real STI can be used.
def descends_from_active_record? = false
def model_class
@model_class ||= name[0..-4].constantize
end
def model_class=(val)
@model_class = val
end
def model_table_name
@model_table_name ||= model_class.table_name
end
end
def members=(*members)
transaction do
remove_all_members
add_members(*members)
end
end
alias replace_children members=
def remove_member(member)
miq_set_memberships.where(:member => member).delete_all
end
alias remove_child remove_member
def remove_all_members
miq_set_memberships.delete_all
end
alias remove_all_children remove_all_members
def add_members(*members)
added = []
transaction do
existing = miq_set_memberships.index_by { |ms| [ms.member_type, ms.member_id] }
members.flatten.each do |member|
raise ArgumentError, "object of type #{member.class} may not be a member of a set of type #{self.class}" unless member.kind_of?(self.class.model_class)
next if existing.include?([member.class.base_class.name, member.id])
miq_set_memberships.create!(:member => member)
added << member
end
end
added
end
alias add_children add_members
alias add_member add_members
alias add_child add_members
end # module ActsAsMiqSet