所以我有一个循环引用问题,我不知道如何解决。所以情况是用户有能力将演员的多部电影列表输入到文本框中。文本保存在虚拟属性中,并在模型的保存回调中解析并提供给模型。理想情况下,我不想更改模型的结构,因为它具有英语意义,并且从数据库的角度来看似乎很正常。
这是结构:
require 'mongoid'
require 'mongo'
class Actor
include Mongoid::Document
field :name
attr_accessible :user_input_films
attr_accessor :user_input_films
before_save :assign_films
embeds_one :filmography
belongs_to :cast
def assign_films
if user_input_films == nil
return
end
user_input_films.split(" ").each do |film|
film = Film.first(conditions: { :name => film})
if film == nil
film = Film.new(:name => film)
film.build_cast
film.save!
end
self.filmography.add_film(film)
end
end
end
class Filmography
include Mongoid::Document
has_many :films
embedded_in :actor
def add_film(film)
films << film
film.cast.actors << self.actor
end
end
class Film
include Mongoid::Document
field :name
embeds_one :cast
belongs_to :filmography
end
class Cast
include Mongoid::Document
embedded_in :film
has_many :actors
end
Mongoid.configure do |config|
config.master = Mongo::Connection.new.db("mydb")
end
connection = Mongo::Connection.new
connection.drop_database("mydb")
database = connection.db("mydb")
actor = Actor.new
actor.build_filmography
actor.user_input_films = "BadFilm1 BadFilm2"
actor.save
puts "actor = #{actor.attributes}"
actor.filmography.films.each do |film|
puts "film = #{film.attributes}"
end
所以结构是:Actor拥有Filmography,它引用了许多Films。并且Film拥有Cast,其中引用了许多演员。问题发生在以下行:
film.cast.actors << self.actor
因为演员随后通过 << 运算符再次保存,循环逻辑再次发生
正如每个人都猜到的错误是:
/home/greg/.rvm/gems/ruby-1.9.2-p290@rails31/gems/mongoid2.2.1/lib/mongoid/fields.rb:307: stack level too deep (SystemStackError)
那么如何在没有循环引用堆栈溢出的情况下保存我的文档呢?
更新:一个想法,我认为一个肮脏的解决方案将是一种添加引用而不保存引用对象的方法。
谢谢