Rails以一种形式创建多个相互关联的对象

时间:2015-03-23 05:18:16

标签: ruby-on-rails-4 activerecord

我有Vehicles模型,其中每辆车都有makemodel。当用户创建车辆时,他们可以从当前可用的品牌和型号中进行选择,也可以创建新的品牌和型号。 makemodel都不包含额外数据,因此它们存储在我用于动态枚举的CommonLookup模型中。

我想根据当前选定的model通过ajax限制make个选项。为此,我在blongs_to模型上为自己创建了CommonLookup关系;换句话说,该类型的任何记录都可以选择在多对一关系中引用相同类型的parent记录。

我遇到的问题实际上是在挽救这种关系。我的模型代码适用于创建不相关的makemodel记录,如下所示:

class Vehicle < ActiveRecord::Base
    belongs_to :make, :class_name => "CommonLookup", :foreign_key => "make_id"
    belongs_to :model, :class_name => "CommonLookup", :foreign_key => "model_id"
    attr_accessor :new_make_name
    attr_accessor :new_model_name

    before_save :create_make_from_name, :create_model_from_name
    def create_make_from_name
        create_make(
            :value => new_make_name
        )
    end

    def create_model_from_name
        create_model(
            :value => new_model_name
        )
    end
end

此代码成功创建了一个带有相关新品牌和型号的车辆,但新品牌和型号并没有相互关联,因为我需要它们。我需要一个多模型到一个制造的关系,我可以用来轻松限制选择。需要明确的是,这个问题与限制选择所必需的ajax部分无关;我专注于创建模型实例本身,以便它们是相关的,所有这些都来自单一形式。

我试图在create_model_from_name回调中设置代码,但无济于事;没有可用于设置关系的第一个回调中创建的对象的可访问引用。我尝试了什么:

def create_model_from_name
    create_model(
        :value => new_model_name,
        :parent => :make
    )
end

但这并没有奏效。任何帮助将不胜感激。

1 个答案:

答案 0 :(得分:0)

我通过组合before_save回调并包含更多逻辑来解决这个问题:

class Vehicle < ActiveRecord::Base
    belongs_to :make, :class_name => "CommonLookup", :foreign_key => "make_id"
    belongs_to :model, :class_name => "CommonLookup", :foreign_key => "model_id"
    attr_accessor :new_make_name
    attr_accessor :new_model_name
    before_save :create_make_and_model_from_names

    def create_make_and_model_from_names
        if not new_model_name.blank?
            if not new_make_name.blank?
                create_model(
                    :value => new_model_name,
                    :parent => create_parent(
                        :value => new_make_name
                    )
                )
            else
                create_model(
                    :value => new_model_name,
                    :parent => model
                )
            end
        end
    end
end

通过设置创建新品牌的方法以及创建新品牌和现有品牌并将其与新品牌相关联,满足了我的要求。最终结果是我的ajax请求更容易设置,因为我可以轻松找到与每个品牌相关联的模型,并将它们放在选项列表中。