rails使用其他模型的数据填充模型

时间:2015-07-25 00:56:36

标签: ruby-on-rails ruby ruby-on-rails-4 activerecord

目前,我有三个模特

# town.rb
class Town < ActiveRecord::Base
  has_many :buildings
end

# building.rb
class Building < ActiveRecord::Base
  belongs_to :town
end

# building_default.rb
class BuildingDefault < ActiveRecord::Base
end

我想在用户创建城镇时发生以下情况:

  1. 使用基于的记录填充用户的Building模型 BuildingDefault模型中包含的信息。
  2. 正确设置每个building.town_id
  3. 例如,假设Building和BuildingDefault的属性:name彼此相同。而BuildingDefault包含两条记录(它实际上包含~125):

    BuildingDefault.all 
    # => <ActiveRecord::Relation [#<BuildingDefault id: 1, name: "cannon">, #<BuildingDefault id: 2, name: "archer">]> 
    

    然后,用户填写一个创建新城镇的表单。我想要使​​用after_create方法复制从BuildingDefaultBuilding的所有内容。在这种情况下,建筑最终将:

    Building.find_by_town_id(1) 
    # => <ActiveRecord::Relation [#<Building id: 69, town_id: 1, name: "cannon">, #<Building id: 70, town_id: 1, name: "archer">]>
    

    有什么方法可以促进这种行为?

2 个答案:

答案 0 :(得分:2)

我认为这应该足够了:

after_create :set_buildings

  private
    def set_buildings
      BuildingDefault.all.each do |default_b|
        buildings.create(id: default_b.id, name: default_b.name)
      end
    end

答案 1 :(得分:0)

我不确定您是否对user_id和town_id感到困惑,或者您真的希望用户模型也与建筑物/城镇相关联。如果是后者,请更新您的代码以包含'belongs_to'用户关联。

目前,我假设您只想关联城镇和建筑物。这是一个多人关系的案例。在这种情况下,我看到有两种选择。

  • 如果您的所有建筑物都没有与个别城镇相关的特殊属性,(即,“Cannon”类型的建筑物对于A镇或B镇具有相同的值),您只需关联has_and_belongs_to_many关系在两者之间创建一个虚拟连接表。然后,您可以通过以下代码将所有建筑物添加到每个城镇:

    @ town.buildings = Building.all

    @ town.save!

  • 如果可能存在与个别城镇的建筑物相关的不同值,则可以在城镇模型中设置has_many buildings, through: :building_town关系,并将这些不同的属性放在中间模型上,在本例中为BuildingTown。

如果您所做的只是复制到实际的建筑模型,我认为不需要保留DefaultBuilding模型。