Ruby On Rails:一对多与一对一

时间:2012-10-24 00:24:01

标签: ruby-on-rails ruby-on-rails-3 activerecord ruby-on-rails-3.2

我有模板和模板版本。模板可以包含许多template_versions,但在任何给定时间只能有一个活动的template_version。我有以下两种型号:

class Template < ActiveRecord:Base
    has_many :template_versions, :class_name => 'TemplateVersion'
    belongs_to :active_version, :class_name => 'TemplateVersion'
end

class TemplateVersion < ActiveRecord:Base
    belongs_to :template
    has_one :template
end

模板只有一个活动的template_version是至关重要的,这就是为什么active_template的键在模板模型上。这一切看起来都很好,直到我在rails控制台中测试它:

t = Template.new()
tv = TemplateVersion.new()
t.active_version = tv
t.save

version = t.active_version //returns version
version.template_id //returns nil

模板知道它的活动template_version,但问题是template_version不知道它属于哪个模板。我猜这是因为在插入数据库时​​,创建了template_version以获取与模板关联的id,然后必须保存该模板以备份模板ID以填充模板版本。

有没有办法实现这一切?

2 个答案:

答案 0 :(得分:1)

您当前设置的问题是您为TemplateVersion定义了两个“模板”方法。如果我有一个tv对象,tv.template可能是has_one或belongs_to模板,ActiveRecord不知道哪个。我不确定你是否可以用某种方式对它们进行别名。

解决方法:在TemplateVersion模型中添加“活动”列并验证只有一个活动的TemplateVersion

class Template < ActiveRecord::Base
    has_many :template_versions, :class_name => 'TemplateVersion'
    has_one :active_version, :class_name => 'TemplateVersion', :conditions => ['active = ?', true]
end

class TemplateVersion < ActiveRecord::Base
    attr_accessible :template_id, :active
    belongs_to :template
    validates :only_one_active

    def only_one_active
      errors.add(:base, "Only one active version per template") if self.active == true and TemplateVersion.where(:active => true, :template_id => self.template_id).count > 0
    end

end

然后,您可以将活动版本作为t.active_version访问,但要设置您需要在TemplateVersion上进行更新的活动版本。

答案 1 :(得分:0)

不确定,但您可以尝试以下方法:

t = Template.new()
tv = TemplateVersion.new()
tv.save
t.active_version = tv
t.save

或可能

t = Template.new()
tv = TemplateVersion.create()
t.active_version = tv
t.save

我相信如果您使用create,则不需要save