diff --git a/lib/models.rb b/lib/models.rb new file mode 100644 index 000000000..4d4f74274 --- /dev/null +++ b/lib/models.rb @@ -0,0 +1,116 @@ +class Models + include ApplicationLib + +=begin + +get list of models + + result = Models.all + +returns + + { + 'Some::Classname1' => { + attributes: ['id', 'name', '...'] + reflections: ...model.reflections... + }, + 'Some::Classname2' => { + attributes: ['id', 'name', '...'] + reflections: ...model.reflections... + }, + } + +=end + + def self.all + all = {} + dir = "#{Rails.root}/app/models/" + Dir.glob( "#{dir}**/*.rb" ) do |entry| + next if entry =~ /application_model/i + next if entry =~ /channel\//i + next if entry =~ /observer\//i + next if entry =~ /store\/provider\//i + entry.gsub!(dir, '') + entry = entry.to_classname + model_class = load_adapter(entry) + next if !model_class + next if !model_class.respond_to? :new + model_object = model_class.new + next if !model_object.respond_to? :attributes + all[model_class] = {} + all[model_class][:attributes] = model_class.attribute_names + all[model_class][:reflections] = model_class.reflections + #puts "rrrr #{all[model_class][:attributes]}" + #puts model.class + #puts " #{model.attribute_names.inspect}" + end + all + end + +=begin + +get reference list of a models + + result = Models.references('User', 2) + +returns + + { + 'Some::Classname1' => { + attributes: ['id', 'name', '...'] + reflections: ...model.reflections... + }, + 'Some::Classname2' => { + attributes: ['id', 'name', '...'] + reflections: ...model.reflections... + }, + } + +=end + + def self.references(object_name, object_id) + object_model = load_adapter(object_name) + object_model.find(object_id) + list = all + references = { + model: {}, + total: 0, + } + + # find relations via attributes + list.each {|model_class, model_attributes| + references[:model][model_class.to_s] = 0 + next if !model_attributes[:attributes] + ['created_by_id', 'updated_by_id'].each {|item| + if model_attributes[:attributes].include?(item) + Rails.logger.info "FOUND (by id) #{model_class}->#{item}!" + references[:model][model_class.to_s] += model_class.where("#{item} = ?", object_id).count + end + } + } + + # find relations via reflections + list.each {|model_class, model_attributes| + next if !model_attributes[:reflections] + model_attributes[:reflections].each{|reflection_key, reflection_value| + next if reflection_value.macro != :belongs_to + if reflection_value.options[:class_name] == object_name + Rails.logger.info "FOUND (by ref without class) #{model_class}->#{reflection_value.name}!" + references[:model][model_class.to_s] += model_class.where("#{reflection_value.name}_id = ?", object_id).count + end + if !reflection_value.options[:class_name] && reflection_value.name == object_name.downcase.to_sym + Rails.logger.info "FOUND (by ref with class) #{model_class}->#{reflection_value.name}!" + references[:model][model_class.to_s] += model_class.where("#{reflection_value.name}_id = ?", object_id).count + end + } + } + + references[:model].each {|k, v| + next if v == 0 + references[:total] += v +puts "#{k}: #{v}" + } + references + end + +end \ No newline at end of file diff --git a/test/unit/model_test.rb b/test/unit/model_test.rb new file mode 100644 index 000000000..6af3d2517 --- /dev/null +++ b/test/unit/model_test.rb @@ -0,0 +1,84 @@ +# encoding: utf-8 +require 'test_helper' + +class ModelTest < ActiveSupport::TestCase + test 'references test' do + + # create base + groups = Group.where( name: 'Users' ) + roles = Role.where( name: ['Agent', 'Admin'] ) + agent1 = User.create_or_update( + login: 'model-agent1@example.com', + firstname: 'Model', + lastname: 'Agent1', + email: 'model-agent1@example.com', + password: 'agentpw', + active: true, + roles: roles, + groups: groups, + updated_at: '2015-02-05 16:37:00', + updated_by_id: 1, + created_by_id: 1, + ) + organization1 = Organization.create_if_not_exists( + name: 'Model Org 1', + updated_at: '2015-02-05 16:37:00', + updated_by_id: 1, + created_by_id: 1, + ) + organization2 = Organization.create_if_not_exists( + name: 'Model Org 2', + updated_at: '2015-02-05 16:37:00', + updated_by_id: agent1.id, + created_by_id: 1, + ) + roles = Role.where( name: 'Customer' ) + customer1 = User.create_or_update( + login: 'model-customer1@example.com', + firstname: 'Model', + lastname: 'Customer1', + email: 'model-customer1@example.com', + password: 'customerpw', + active: true, + organization_id: organization1.id, + roles: roles, + updated_at: '2015-02-05 16:37:00', + updated_by_id: 1, + created_by_id: 1, + ) + customer2 = User.create_or_update( + login: 'model-customer2@example.com', + firstname: 'Model', + lastname: 'Customer2', + email: 'model-customer2@example.com', + password: 'customerpw', + active: true, + organization_id: nil, + roles: roles, + updated_at: '2015-02-05 16:37:00', + updated_by_id: agent1.id, + created_by_id: 1, + ) + customer3 = User.create_or_update( + login: 'model-customer3@example.com', + firstname: 'Model', + lastname: 'Customer3', + email: 'model-customer3@example.com', + password: 'customerpw', + active: true, + organization_id: nil, + roles: roles, + updated_at: '2015-02-05 16:37:00', + updated_by_id: agent1.id, + created_by_id: agent1.id, + ) + + references = Models.references('User', agent1.id) + + 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