在调用create之前将主记录添加到表中

时间:2015-10-09 08:04:21

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

我有ProjectList型号。列表模型acts_as_tree(因此,每个列表都可以包含其他列表作为子项)。

# Project model
has_many :lists

# List model 
belongs_to :project
acts_as_tree

问题:
我想将每个新创建的列表(未指定parent_id)包含到某些主列表中。默认情况下,但我不知道如何确保主列表始终存在。

可能的解决方案:
我认为我需要首先覆盖project.lists.create来创建主列表(如果它不存在),然后才创建新列表。

我不确定如何妥善优雅地完成所有这些工作。任何帮助将不胜感激,谢谢!

我尝试过以下操作并失败了,因为create被反复调用,它是一个无限递归:

# List model
before_create :create_master_list

private

def create_master_list
  self.project.lists.where(id: 9999).first_or_create do |master_list|
    master_list.id = 9999
  end
end
输入Project.find(1).lists.create到rails控制台时输出错误:

SELECT  `lists`.* FROM `lists` WHERE `lists`.`id` = 1000 AND `lists`.`id` = 1000 AND `lists`.`id` = 1000 AND `lists`.`id` = 1000 AND `lists`.`id` = 1000 AND ...

2 个答案:

答案 0 :(得分:1)

ActiveRecord的first_or_create可能就是您正在寻找的内容。如果不存在,它将创建并返回一条新记录。

project.lists.where(parent_id: nil).first_or_create

答案 1 :(得分:1)

您应该在项目的after_create挂钩上创建主列表,以确保它始终存在

在项目模型中的某些内容

#Project Model
after_create :create_master_list

  private
    def :create_master_list
      List.new(project_id: self.id, master: true)
    end

#List model
before_create :add_to_master_list, if: "parent_id.nil?"

private
def :add_to_master_list
  self.parent_id = get_project_master_list.id
end

def get_project_master_list
  return self.project.lists.where(master: true).first_or_create
end