-
Notifications
You must be signed in to change notification settings - Fork 18
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Multiple Databases #18
Comments
Hi @yelvert!
Thank you ;)
An interesting case and we didn't think about this when we developed Сlowne. We always use the source class as the base class for cloning and it can't be overridden, but we have a magic init_as declaration. At first, define models and schemas require 'clowne'
require 'activerecord'
require 'sqlite3'
class ApplicationRecord < ::ActiveRecord::Base
self.abstract_class = true
establish_connection(adapter: 'sqlite3', database: 'file:memdb2?mode=memory')
end
class Widget < ApplicationRecord; end
module GuestHouse
class ApplicationRecord < ::ActiveRecord::Base
self.abstract_class = true
establish_connection(adapter: 'sqlite3', database: 'file:memdb1?mode=memory')
end
class Widget < ApplicationRecord; end
end
ActiveRecord::Schema.define do
self.verbose = false
ApplicationRecord.connection.create_table :widgets, force: true do |t|
t.string :name, null: false
t.string :country, null: false
end
GuestHouse::ApplicationRecord.connection.create_table :widgets, force: true do |t|
t.string :name, null: false
t.string :country, null: false
end
end Then implement cloners module AsAlien
def self.included(base)
base.class_eval do
init_as do |source, params|
target_class =
if target_scope = params[:target_scope]
target_scope.const_get(source.class.name.demodulize)
else
source.class
end
target_class.new(source.attributes)
end
end
end
end
class WidgetCloner < Clowne::Cloner
include AsAlien
finalize do |_source, record|
record.name = "[cloned] " + record.name
end
end
class GuestHouse::WidgetCloner < Clowne::Cloner
include AsAlien
finalize do |_source, record|
record.name = "[guest cloned] " + record.name
end
end And call it w1 = Widget.create(name: 'News', country: 'ru')
w2 = GuestHouse::Widget.create(name: 'Weather', country: 'us')
# WidgetCloner:
WidgetCloner.call(w1)
=> #<Widget:0x00007fbb349c1f20 id: 1, name: "[cloned] News", country: "ru">
WidgetCloner.call(w2)
=> #<GuestHouse::Widget:0x00007fbb332c5c40 id: 1, name: "[cloned] Weather", country: "us">
WidgetCloner.call(w2, target_scope: Object)
=> #<Widget:0x00007fbb3209cd98 id: 1, name: "[cloned] Weather", country: "us">
# GuestHouse::WidgetCloner:
GuestHouse::WidgetCloner.call(w1)
=> #<Widget:0x00007fbb349311f0 id: 1, name: "[guest cloned] News", country: "ru">
GuestHouse::WidgetCloner.call(w2)
=> #<GuestHouse::Widget:0x00007fbb348f3b70 id: 1, name: "[guest cloned] Weather", country: "us">
GuestHouse::WidgetCloner.call(w1, target_scope: GuestHouse)
=> #<GuestHouse::Widget:0x00007fbb348b9ec0 id: 1, name: "[guest cloned] News", country: "ru"> Since we can proxy the parameters through all associations, this will allow you to clone objects under one scope (DB). |
First off, very nice looking gem, I actually just started work on something very similar, except my use case involves cloning records from a separate, but (mostly) identical database. I'm currently using a separate
ApplicationRecord
base class, for handling the alternate models to clone from, that looks like this.So, if I have:
Then
Widget
s can be cloned fromGuestHouse::Widget
sCould this gem handle that use case out of the box, or would it need some additional development, and if so, could you point me to a starting place?
The text was updated successfully, but these errors were encountered: