Comments (5)
@ssnickolay It works beautifully, thanks a lot!
from clowne.
Hey @vitobotta !
Let's me quickly clarify your setup:
class A < ActiveRecord::Base
has_many :b_records, class_name: "B"
end
class B < ActiveRecord::Base
belongs_to :a_record, class_name: "A"
end
And you want to do something like this:
class ACloner < Clowne::Cloner
include_associations :b_records
end
a1 = A.sample
a1.b_record_ids = [B.sample.id, B.sample.id]
operation = ACloner.call(a1)
operation.persist
a2 = operation.to_record
puts a2.b_records_ids
# ???
If so, in this case we will have:
a2.b_record_ids == a1.b_record_ids
# false
because a2 clearly will have a relation with cloned b_records (not with a1.b_records). This relation cloning logic works as deep as you have enough imagination)
p/s/ If I didn't understand you correctly or you have a more complex case - just write here and I will help if I can;)
from clowne.
Hi @ssnickolay !
Thanks a lot for replying. I am trying to use this gem now and I am almost there.
I have three models: ThemeVersion has many Templates, and Template has many TemplateVersions. These are the cloners:
class ThemeVersionCloner < Clowne::Cloner
adapter :active_record
include_association :templates, clone_with: TemplateCloner
finalize do |_source, record, params|
record.current = false
record.description = params[:description]
record.preview_token = SecureRandom.hex(16)
end
end
class TemplateCloner < Clowne::Cloner
adapter :active_record
include_association :template_versions, clone_with: TemplateVersionCloner
end
class TemplateVersionCloner < Clowne::Cloner
adapter :active_record
finalize do |source, record, params|
record.path = _source.path.gsub(/\/\d+\//, "/#{record.template.theme_version.id}/")
end
end
I am having two problems:
-
The line
record.path = _source.path.gsub(/\/\d+\//, "/#{record.template.theme_version.id}/")
is not working as expected, becauserecord.template
points to the template of the source template version, so the theme version id to replace in thepath
attribute is wrong. I need the theme version id of the cloned parent (this has to do with a CMS where I am loading liquid templates from the database, and everything is versioned; the path thing is to be able to have multiple templates with the same path for different theme versions, so that the resolver can work properly). So the question is, how can I access the cloned parent? -
When dealing with nested models and accessing associations like the parent of the parent, there are a ton of SQL queries. Is there any way to optimise this?
-
Can I somehow pass parameters to the
include_association
macro? This may help with 1 and 2.
Thanks in advance!
from clowne.
I got it working with after_persist
, but it makes a lot of DB queries. If it's possible to optimise somehow it would be great.
BTW the Documentation link in the README is barely noticeable! Maybe it could be made more prominent. I didn't notice it before so I didn't know about after_persist
.
from clowne.
BTW the Documentation link in the README is barely noticeable! Maybe it could be made more prominent. I didn't notice it before so I didn't know about after_persist.
Hm, sounds reasonable. I'll think what we can do. Thanks 👍
When dealing with nested models and accessing associations like the parent of the parent, there are a ton of SQL queries. Is there any way to optimise this?
You can preload all associations using eager loading
Can I somehow pass parameters to the include_association macro? This may help with 1 and 2.
I think this should helpful for you: https://clowne.evilmartians.io/#/parameters
I got it working with after_persist, but it makes a lot of DB queries.
You can try to implement a store to collect all changes and use bulk upsert (new Rails 6 feature):
class TemplateVersionCloner < Clowne::Cloner
# adapter :active_record we can skip it
after_persist do |origin, clone, mapper:, template_version_store: |
cloned_version = mapper.clone_of(origin.bio)
template_version_store.unshift({
id: clone.id,
path: _source.path.gsub(/\/\d+\//, "/#{cloned_version.template.theme_version.id}/")
}) # add to the store what we need to change
end
end
template_version_store = []
theme = Theme.includes(templates: :template_versions).find(params[:id]) # preload what we will clone
operation = ThemeVersionCloner.call(theme, {template_version_store: template_version_store})
operation.persist
puts template_version_store
# list of collected changes
TemplateVersion.upsert_all(template_version_store, unique_by: :id)
from clowne.
Related Issues (20)
- Nested params HOT 14
- Multiple Databases HOT 1
- How to access the target cloned parent? HOT 12
- Plans to support belongs to and has many through? HOT 1
- `dependent: :destroy` option on association destroys models related to source after cloning HOT 3
- Is there support for self-referential tables HOT 1
- Weird bug upgrading from 0.2.0 to 1.1.0 HOT 2
- Active Storage & Action Text HOT 4
- Migrate to Standard HOT 3
- Association couldn't be found, Rails 4.1.8 HOT 3
- polymorphic association HOT 2
- Is it possible to clone a record to a different table? HOT 3
- Which association is created first if you have multiple associations? HOT 2
- Ruby 3.0 compatibility HOT 5
- Is there possible to use traits in trait?
- Release with mapper access in `after_clone` HOT 2
- Nested include_association duplication HOT 7
- Is it possible to ignore an attribute? HOT 3
- Question HOT 1
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from clowne.