diff --git a/app/models/user.rb b/app/models/user.rb index 655002b4a16e0db6faa79368658ed3c1927e3fe2..165a95fec397b24c4280eab6b758cc63e90bea7f 100644 --- a/app/models/user.rb +++ b/app/models/user.rb @@ -1,7 +1,30 @@ +# For now, the User model is being persisted in two repositories: +# * On postgres, using ActiveRecord +# * OrientDb as graph nodes +# +# Goals: Keep the users in both (postgres, orientdb) +# +# Devise Controllers -----> User model (with active record api) +# / +# Client -/ +# \ +# \ +# Portal Mec Controllers -> User repository +# +# How works? +# For keep simple, user node in orientdb stored only a reference to the real user in postgres. +# So, the user node will be only created or destroyed. +# +# When devise create user, the active record hooks will sync with user repository +# And, when the application call the user repository, it will keep sync with active record user model class User < ActiveRecord::Base # Include default devise modules. Others available are: # :confirmable, :lockable, :timeoutable and :omniauthable devise :database_authenticatable, :registerable, :recoverable, :rememberable, :trackable, :validatable has_and_belongs_to_many :roles + + after_create SyncUserRepositoryService.new + after_destroy SyncUserRepositoryService.new end + diff --git a/app/repositories/active_record/user_repository.rb b/app/repositories/active_record/user_repository.rb deleted file mode 100644 index dcee291569767086033308fab1bf9692830bab5b..0000000000000000000000000000000000000000 --- a/app/repositories/active_record/user_repository.rb +++ /dev/null @@ -1,30 +0,0 @@ -module ActiveRecord - class UserRepository - class MethodNotImplementedError < NoMethodError; end - - def find(*ids) - User.find *ids - end - - def all - User.all - end - - def save(user) - user.save - end - - def update(user, params={}) - user.update params - end - - def destroy(user) - user.destroy - end - - def ensure_is_graph_node(user) - raise MethodNotImplementedError, 'This method is implement only for graph repositories' - end - - end -end \ No newline at end of file diff --git a/app/repositories/orient_db/user_repository.rb b/app/repositories/orient_db/user_repository.rb index 2c912f36825b4ba4b22bdeb3f950c9c22529ec32..ef73202db25fc2d2aa67df52c9259451e638537f 100644 --- a/app/repositories/orient_db/user_repository.rb +++ b/app/repositories/orient_db/user_repository.rb @@ -1,42 +1,12 @@ module OrientDb class UserRepository < Base - def find(*ids) + def create_graph_node(user) + connection.command sprintf("INSERT INTO User (p_id) VALUES (%d)", user.id) end - def all - end - - def save(user) - connection.command sprintf("INSERT INTO User (title, u_id) VALUES ('%s', %d)", user.email, user.id) - end - - def update(params={}) - end - - def destroy(user) - end - - def find_by_email(email) - connection.query sprintf("SELECT FROM User WHERE @email = '%s'", email) - end - - def ensure_is_graph_node(user) - if find_by_email(user.email).nil? - return save(user) - end - end - - def find_by_id(rid) - connection.query "SELECT FROM User WHERE @rid=#{rid}" - end - - def author_of(rid) - connection.query "SELECT expand(in) FROM (SELECT expand(out_author_of) FROM User WHERE @rid=#{rid})" - end - - def has(rid) - connection.query "SELECT expand(in) FROM (SELECT expand(out_has) FROM User WHERE @rid=#{rid})" + def destroy_graph_node(user) + connection.command sprintf("DELETE FROM User WHERE p_id = %d", user.id) end end diff --git a/app/repositories/user_repository_proxy.rb b/app/repositories/user_repository_proxy.rb new file mode 100644 index 0000000000000000000000000000000000000000..93da422795d2e2c6df506cfefe3401f74d73b5b6 --- /dev/null +++ b/app/repositories/user_repository_proxy.rb @@ -0,0 +1,33 @@ +# This proxy will keep postgres and orientdb syncronized +# When some client call UserRepositoryProxy, it will delegate the missing methods for ActiveRecord User model +class UserRepositoryProxy + + def initialize(orientdb_user_repository) + @orientdb_user_repository = orientdb_user_repository + end + + def create_graph_node(user) + orientdb_user_repository.create_graph_node user + end + + def destroy_graph_node(user) + orientdb_user_repository.destroy_graph_node user + end + + def method_missing(method_name, *arguments, &block) + if method_name.to_s =~ /user_(.*)/ + User.send($1, *arguments, &block) + else + super + end + end + + def respond_to?(method_name, include_private = false) + User.respond_to?(method_name) || super + end + + private + + attr_reader :orientdb_user_repository + +end \ No newline at end of file diff --git a/app/services/sync_user_repository_service.rb b/app/services/sync_user_repository_service.rb new file mode 100644 index 0000000000000000000000000000000000000000..c23d9b036441833a52049e62b646cf40d652f765 --- /dev/null +++ b/app/services/sync_user_repository_service.rb @@ -0,0 +1,17 @@ +class SyncUserRepositoryService + + def after_create(user) + user_repository.create_graph_node user + end + + def after_destroy(user) + user_repository.destroy_graph_node user + end + + private + + def user_repository + Portalmec::Application.repository.for :user + end + +end \ No newline at end of file diff --git a/config/initializers/repositories.rb b/config/initializers/repositories.rb index f24ad0252e7dcd893ba6294191b0a402d51c0e83..5e8ae001086805bc9485080e7e20d0d07ef0a944 100644 --- a/config/initializers/repositories.rb +++ b/config/initializers/repositories.rb @@ -3,7 +3,7 @@ Repository::Environments.create :development do |repository| repository.register :edge, OrientDb::EdgeRepository.new(OrientDb::Client.instance) repository.register :mainPage, OrientDb::MainPageRepository.new(OrientDb::Client.instance) repository.register :webLink, OrientDb::WeblinkRepository.new(OrientDb::Client.instance) - repository.register :user, ActiveRecord::UserRepository.new + repository.register :user, UserRepositoryProxy.new(OrientDb::UserRepository.new(OrientDb::Client.instance)) repository.register :carousel, OrientDb::CarouselRepository.new(OrientDb::Client.instance) end @@ -13,7 +13,7 @@ Repository::Environments.create :test do |repository| repository.register :mainPage, OrientDb::MainPageRepository.new(OrientDb::Client.instance) repository.register :webLink, OrientDb::WeblinkRepository.new(OrientDb::Client.instance) repository.register :carousel, OrientDb::CarouselRepository.new(OrientDb::Client.instance) - repository.register :user, ActiveRecord::UserRepository.new + repository.register :user, UserRepositoryProxy.new(OrientDb::UserRepository.new(OrientDb::Client.instance)) end Repository::Environments.create :production do |repository| @@ -22,5 +22,5 @@ Repository::Environments.create :production do |repository| repository.register :mainPage, OrientDb::MainPageRepository.new(OrientDb::Client.instance) repository.register :webLink, OrientDb::WeblinkRepository.new(OrientDb::Client.instance) repository.register :carousel, OrientDb::CarouselRepository.new(OrientDb::Client.instance) - repository.register :user, ActiveRecord::UserRepository.new + repository.register :user, UserRepositoryProxy.new(OrientDb::UserRepository.new(OrientDb::Client.instance)) end \ No newline at end of file diff --git a/test/repositories/active_record/user_repository_test.rb b/test/repositories/active_record/user_repository_test.rb deleted file mode 100644 index d473b4bad2e948134c2bced3ffeaa4969d1ca366..0000000000000000000000000000000000000000 --- a/test/repositories/active_record/user_repository_test.rb +++ /dev/null @@ -1,9 +0,0 @@ -require 'test_helper' - -class ActiveRecord::UserRepositoryTest < ActiveSupport::TestCase - - def setup - @repo = ActiveRecord::UserRepository.new - end - -end \ No newline at end of file