Как вы можете клонировать записи и их отношения в рельсах?
У меня есть приложение с og_objects
, og_actions
, а также stories
Я создал способ создать клон этого приложения.
Я сейчас пытаюсь продублировать og_objects
, og_actions
а также stories
в клон, но я застреваю.
Я застреваю в двух местах.
1. Когда я создаю клон, объекты, действия, истории перемещаются в новый клон, но они не дублируются, то есть родительское приложение теряет их.
2. Я получаю сообщение об ошибке, что у моего нового клона нет свойства og_objects. В частности, ошибка:
ActiveModel::MissingAttributeError (can't write unknown attribute `og_actions'):
app/models/app.rb:39:in `block in populate'
app/models/app.rb:36:in `populate'
app/models/app_generator.rb:15:in `generate'
app/controllers/apps_controller.rb:12:in `create'
Вот код, который у меня есть:
class App < ActiveRecord::Base
validates :name, :presence => true, :uniqueness => {:scope => :dev_mode}
validates :user_id, :presence => true
before_validation :validate_app
belongs_to :user
has_many :og_actions
has_many :og_objects
has_many :stories
has_many :log_reports
has_many :clones, class_name: "App", foreign_key: "parent_id"
belongs_to :parent_app, class_name: "App"
def self.dev_modes
['development', 'stage', 'production']
end
def is_clone?
!!self.parent_id
end
def clone_ids
if !is_clone?
self.clones.all.map(&id)
end
end
def populate
p "doing populate"
p self.clones
p "original clones"
new_og_actions = self.og_actions.dup
new_og_objects = self.og_objects.dup
new_stories = self.stories.dup
self.clones.each do |c|
p "updating ->"
p c
c[:og_actions] = new_og_actions
c[:og_objects] = new_og_objects
c[:stories] = new_stories
end
end
#Other irrelevant code here:
В моем контроллере у меня есть генератор, и у меня есть следующий код:
if @parent_id.length > 0
parent_app = App.find(@parent_id)
App.create_with(og_actions: parent_app.og_actions.dup, og_objects: parent_app.og_objects.dup, stories:parent_app.stories.dup, parent_id: @parent_id, user_id: @user_id, app_id:@app_id, app_secret: @app_secret).find_or_create_by!(name: @name, dev_mode: 'clone')
parent_app.populate
else
1 ответ
Чтобы заставить это работать, я использовал метод first_or_initialize и создал отношения, если я не смог найти запись, иначе я обновил запись.
Я изменил метод заполнения следующим образом:
def populate
p "doing populate"
p self.clones
p "original clones"
new_og_objects = self.og_objects.dup
new_stories = self.stories.dup
self.clones.each do |c|
p "updating ->"
self.og_actions.each do | oa |
new_og_actions = OgAction.create(oa.attributes.merge({app_id:c.id, id: nil }))
c.og_actions.first_or_initialize(new_og_actions)
end
self.og_objects.each do |oo|
new_og_objects = OgObject.create(oo.attributes.merge({app_id:c.id, id: nil }))
c.og_objects.first_or_initialize(new_og_objects)
end
self.stories.each do | s|
new_stories = Story.create(s.attributes.merge({app_id:c.id, id: nil }))
c.stories.first_or_initialize(new_stories)
end
p c
end
end
Я также удалил создание этих символов в AppGenerator следующим образом:
if @parent_id.length > 0
parent_app = App.find(@parent_id)
App.create_with(parent_id: @parent_id, user_id: @user_id, app_id:@app_id, app_secret: @app_secret).find_or_create_by!(name: @name, dev_mode: 'clone')
parent_app.populate
else