Improved model helpers.
This commit is contained in:
parent
359f276c87
commit
54f11be47b
2 changed files with 211 additions and 30 deletions
136
lib/models.rb
136
lib/models.rb
|
@ -40,9 +40,9 @@ returns
|
||||||
all[model_class] = {}
|
all[model_class] = {}
|
||||||
all[model_class][:attributes] = model_class.attribute_names
|
all[model_class][:attributes] = model_class.attribute_names
|
||||||
all[model_class][:reflections] = model_class.reflections
|
all[model_class][:reflections] = model_class.reflections
|
||||||
|
#puts model_class
|
||||||
#puts "rrrr #{all[model_class][:attributes]}"
|
#puts "rrrr #{all[model_class][:attributes]}"
|
||||||
#puts model.class
|
#puts " #{model_class.attribute_names.inspect}"
|
||||||
#puts " #{model.attribute_names.inspect}"
|
|
||||||
end
|
end
|
||||||
all
|
all
|
||||||
end
|
end
|
||||||
|
@ -57,38 +57,51 @@ returns
|
||||||
|
|
||||||
{
|
{
|
||||||
'Some::Classname1' => {
|
'Some::Classname1' => {
|
||||||
attributes: ['id', 'name', '...']
|
attribute1: 12,
|
||||||
reflections: ...model.reflections...
|
attribute2: 6,
|
||||||
},
|
},
|
||||||
'Some::Classname2' => {
|
'Some::Classname2' => {
|
||||||
attributes: ['id', 'name', '...']
|
updated_by_id: 12,
|
||||||
reflections: ...model.reflections...
|
created_by_id: 6,
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
|
||||||
=end
|
=end
|
||||||
|
|
||||||
def self.references(object_name, object_id)
|
def self.references(object_name, object_id)
|
||||||
|
|
||||||
|
# check if model exists
|
||||||
object_model = load_adapter(object_name)
|
object_model = load_adapter(object_name)
|
||||||
object_model.find(object_id)
|
object_model.find(object_id)
|
||||||
|
|
||||||
list = all
|
list = all
|
||||||
references = {
|
references = {}
|
||||||
model: {},
|
|
||||||
total: 0,
|
|
||||||
}
|
|
||||||
|
|
||||||
# find relations via attributes
|
# find relations via attributes
|
||||||
list.each {|model_class, model_attributes|
|
ref_attributes = ["#{object_name.downcase}_id"]
|
||||||
references[:model][model_class.to_s] = 0
|
|
||||||
next if !model_attributes[:attributes]
|
|
||||||
%w(created_by_id updated_by_id).each {|item|
|
|
||||||
|
|
||||||
|
# for users we do not define relations for created_by_id &
|
||||||
|
# updated_by_id - add it here directly
|
||||||
|
if object_name == 'User'
|
||||||
|
ref_attributes.push 'created_by_id'
|
||||||
|
ref_attributes.push 'updated_by_id'
|
||||||
|
end
|
||||||
|
list.each {|model_class, model_attributes|
|
||||||
|
if !references[model_class.to_s]
|
||||||
|
references[model_class.to_s] = {}
|
||||||
|
end
|
||||||
|
|
||||||
|
next if !model_attributes[:attributes]
|
||||||
|
ref_attributes.each {|item|
|
||||||
next if !model_attributes[:attributes].include?(item)
|
next if !model_attributes[:attributes].include?(item)
|
||||||
|
|
||||||
count = model_class.where("#{item} = ?", object_id).count
|
count = model_class.where("#{item} = ?", object_id).count
|
||||||
next if count == 0
|
next if count == 0
|
||||||
|
if !references[model_class.to_s][item]
|
||||||
|
references[model_class.to_s][item] = 0
|
||||||
|
end
|
||||||
Rails.logger.debug "FOUND (by id) #{model_class}->#{item} #{count}!"
|
Rails.logger.debug "FOUND (by id) #{model_class}->#{item} #{count}!"
|
||||||
references[:model][model_class.to_s] += count
|
references[model_class.to_s][item] += count
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -98,30 +111,103 @@ returns
|
||||||
model_attributes[:reflections].each {|_reflection_key, reflection_value|
|
model_attributes[:reflections].each {|_reflection_key, reflection_value|
|
||||||
|
|
||||||
next if reflection_value.macro != :belongs_to
|
next if reflection_value.macro != :belongs_to
|
||||||
|
col_name = "#{reflection_value.name}_id"
|
||||||
|
next if ref_attributes.include?(col_name)
|
||||||
|
|
||||||
if reflection_value.options[:class_name] == object_name
|
if reflection_value.options[:class_name] == object_name
|
||||||
count = model_class.where("#{reflection_value.name}_id = ?", object_id).count
|
count = model_class.where("#{col_name} = ?", object_id).count
|
||||||
next if count == 0
|
next if count == 0
|
||||||
Rails.logger.debug "FOUND (by ref without class) #{model_class}->#{reflection_value.name} #{count}!"
|
if !references[model_class.to_s][col_name]
|
||||||
references[:model][model_class.to_s] += count
|
references[model_class.to_s][col_name] = 0
|
||||||
|
end
|
||||||
|
Rails.logger.debug "FOUND (by ref without class) #{model_class}->#{col_name} #{count}!"
|
||||||
|
references[model_class.to_s][col_name] += count
|
||||||
end
|
end
|
||||||
|
|
||||||
next if reflection_value.options[:class_name]
|
next if reflection_value.options[:class_name]
|
||||||
next if reflection_value.name != object_name.downcase.to_sym
|
next if reflection_value.name != object_name.downcase.to_sym
|
||||||
|
|
||||||
count = model_class.where("#{reflection_value.name}_id = ?", object_id).count
|
count = model_class.where("#{col_name} = ?", object_id).count
|
||||||
next if count == 0
|
next if count == 0
|
||||||
|
if !references[model_class.to_s][col_name]
|
||||||
Rails.logger.debug "FOUND (by ref with class) #{model_class}->#{reflection_value.name} #{count}!"
|
references[model_class.to_s][col_name] = 0
|
||||||
references[:model][model_class.to_s] += count
|
end
|
||||||
|
Rails.logger.debug "FOUND (by ref with class) #{model_class}->#{col_name} #{count}!"
|
||||||
|
references[model_class.to_s][col_name] += count
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
references[:model].each {|_k, v|
|
# cleanup, remove models with empty references
|
||||||
next if v == 0
|
references.each {|k, v|
|
||||||
references[:total] += v
|
next if !v.empty?
|
||||||
|
references.delete(k)
|
||||||
}
|
}
|
||||||
|
|
||||||
references
|
references
|
||||||
end
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
get reference total of a models
|
||||||
|
|
||||||
|
count = Models.references_total('User', 2)
|
||||||
|
|
||||||
|
returns
|
||||||
|
|
||||||
|
count # 1234
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def self.references_total(object_name, object_id)
|
||||||
|
references = self.references(object_name, object_id)
|
||||||
|
total = 0
|
||||||
|
references.each {|_model, model_references|
|
||||||
|
model_references.each {|_col, count|
|
||||||
|
total += count
|
||||||
|
}
|
||||||
|
}
|
||||||
|
total
|
||||||
|
end
|
||||||
|
|
||||||
|
=begin
|
||||||
|
|
||||||
|
merge model references to other model
|
||||||
|
|
||||||
|
result = Models.merge('User', 2, 4711)
|
||||||
|
|
||||||
|
returns
|
||||||
|
|
||||||
|
true # false
|
||||||
|
|
||||||
|
=end
|
||||||
|
|
||||||
|
def self.merge(object_name, object_id_primary, object_id_to_merge, force = false)
|
||||||
|
|
||||||
|
# if lower x references to update, do it right now
|
||||||
|
if force
|
||||||
|
total = Models.references_total(object_name, object_id_to_merge)
|
||||||
|
if total > 1000
|
||||||
|
fail "Can't merge object because object has more then 1000 (#{total}) references, please contact your system administrator."
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
references = Models.references(object_name, object_id_to_merge)
|
||||||
|
references.each {|model, attributes|
|
||||||
|
model_object = Object.const_get(model)
|
||||||
|
items_to_update = {}
|
||||||
|
attributes.each {|attribute, _count|
|
||||||
|
#puts "-> #{model}: #{attribute}->#{object_id_to_merge}->#{object_id_primary}"
|
||||||
|
model_object.where("#{attribute} = ?", object_id_to_merge).each {|item|
|
||||||
|
if !items_to_update[item.id]
|
||||||
|
items_to_update[item.id] = item
|
||||||
|
end
|
||||||
|
items_to_update[item.id][attribute.to_sym] = object_id_primary
|
||||||
|
}
|
||||||
|
}
|
||||||
|
items_to_update.each {|_id, item|
|
||||||
|
item.save
|
||||||
|
}
|
||||||
|
}
|
||||||
|
true
|
||||||
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -20,6 +20,19 @@ class ModelTest < ActiveSupport::TestCase
|
||||||
updated_by_id: 1,
|
updated_by_id: 1,
|
||||||
created_by_id: 1,
|
created_by_id: 1,
|
||||||
)
|
)
|
||||||
|
agent2 = User.create_or_update(
|
||||||
|
login: 'model-agent2@example.com',
|
||||||
|
firstname: 'Model',
|
||||||
|
lastname: 'Agent2',
|
||||||
|
email: 'model-agent2@example.com',
|
||||||
|
password: 'agentpw',
|
||||||
|
active: true,
|
||||||
|
roles: roles,
|
||||||
|
groups: groups,
|
||||||
|
updated_at: '2015-02-05 17:37:00',
|
||||||
|
updated_by_id: agent1.id,
|
||||||
|
created_by_id: 1,
|
||||||
|
)
|
||||||
organization1 = Organization.create_if_not_exists(
|
organization1 = Organization.create_if_not_exists(
|
||||||
name: 'Model Org 1',
|
name: 'Model Org 1',
|
||||||
updated_at: '2015-02-05 16:37:00',
|
updated_at: '2015-02-05 16:37:00',
|
||||||
|
@ -73,12 +86,94 @@ class ModelTest < ActiveSupport::TestCase
|
||||||
created_by_id: agent1.id,
|
created_by_id: agent1.id,
|
||||||
)
|
)
|
||||||
|
|
||||||
references = Models.references('User', agent1.id)
|
# user
|
||||||
|
|
||||||
|
# verify agent1
|
||||||
|
references1 = Models.references('User', agent1.id)
|
||||||
|
|
||||||
|
assert_equal(references1['User']['updated_by_id'], 3)
|
||||||
|
assert_equal(references1['User']['created_by_id'], 1)
|
||||||
|
assert_equal(references1['Organization']['updated_by_id'], 1)
|
||||||
|
assert(!references1['Group'])
|
||||||
|
|
||||||
|
references_total1 = Models.references_total('User', agent1.id)
|
||||||
|
assert_equal(references_total1, 7)
|
||||||
|
|
||||||
|
# verify agent2
|
||||||
|
references2 = Models.references('User', agent2.id)
|
||||||
|
|
||||||
|
assert(!references2['User'])
|
||||||
|
assert(!references2['Organization'])
|
||||||
|
assert(!references2['Group'])
|
||||||
|
assert(references2.empty?)
|
||||||
|
|
||||||
|
references_total2 = Models.references_total('User', agent2.id)
|
||||||
|
assert_equal(references_total2, 0)
|
||||||
|
|
||||||
|
Models.merge('User', agent2.id, agent1.id)
|
||||||
|
|
||||||
|
# verify agent1
|
||||||
|
references1 = Models.references('User', agent1.id)
|
||||||
|
|
||||||
|
assert(!references1['User'])
|
||||||
|
assert(!references1['Organization'])
|
||||||
|
assert(!references1['Group'])
|
||||||
|
assert(references1.empty?)
|
||||||
|
|
||||||
|
references_total1 = Models.references_total('User', agent1.id)
|
||||||
|
assert_equal(references_total1, 0)
|
||||||
|
|
||||||
|
# verify agent2
|
||||||
|
references2 = Models.references('User', agent2.id)
|
||||||
|
|
||||||
|
assert_equal(references2['User']['updated_by_id'], 3)
|
||||||
|
assert_equal(references2['User']['created_by_id'], 1)
|
||||||
|
assert_equal(references2['Organization']['updated_by_id'], 1)
|
||||||
|
assert(!references2['Group'])
|
||||||
|
|
||||||
|
references_total2 = Models.references_total('User', agent2.id)
|
||||||
|
assert_equal(references_total2, 7)
|
||||||
|
|
||||||
|
# org
|
||||||
|
|
||||||
|
# verify agent1
|
||||||
|
references1 = Models.references('Organization', organization1.id)
|
||||||
|
|
||||||
|
assert_equal(references1['User']['organization_id'], 1)
|
||||||
|
assert(!references1['Organization'])
|
||||||
|
assert(!references1['Group'])
|
||||||
|
|
||||||
|
references_total1 = Models.references_total('Organization', organization1.id)
|
||||||
|
assert_equal(references_total1, 1)
|
||||||
|
|
||||||
|
# verify agent2
|
||||||
|
references2 = Models.references('Organization', organization2.id)
|
||||||
|
|
||||||
|
assert(references2.empty?)
|
||||||
|
|
||||||
|
references_total2 = Models.references_total('Organization', organization2.id)
|
||||||
|
assert_equal(references_total2, 0)
|
||||||
|
|
||||||
|
Models.merge('Organization', organization2.id, organization1.id)
|
||||||
|
|
||||||
|
# verify agent1
|
||||||
|
references1 = Models.references('Organization', organization1.id)
|
||||||
|
|
||||||
|
assert(references1.empty?)
|
||||||
|
|
||||||
|
references_total1 = Models.references_total('Organization', organization1.id)
|
||||||
|
assert_equal(references_total1, 0)
|
||||||
|
|
||||||
|
# verify agent2
|
||||||
|
references2 = Models.references('Organization', organization2.id)
|
||||||
|
|
||||||
|
assert_equal(references2['User']['organization_id'], 1)
|
||||||
|
assert(!references2['Organization'])
|
||||||
|
assert(!references2['Group'])
|
||||||
|
|
||||||
|
references_total2 = Models.references_total('Organization', organization2.id)
|
||||||
|
assert_equal(references_total2, 1)
|
||||||
|
|
||||||
assert_equal(references[:model]['User'], 3)
|
|
||||||
assert_equal(references[:model]['Organization'], 1)
|
|
||||||
assert_equal(references[:model]['Group'], 0)
|
|
||||||
assert_equal(references[:total], 6)
|
|
||||||
end
|
end
|
||||||
|
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in a new issue