我有一个项目模型,用于在创建时在特定项目中自动生成部门。这包含在projects
模型中:
class Project < ActiveRecord::Base
attr_accessible :title, :departments_attributes, :positions_attributes, :id
belongs_to :user
has_many :departments
has_many :positions
validates :title, presence: true
before_create :set_departments
accepts_nested_attributes_for :departments
accepts_nested_attributes_for :positions
private
def set_departments
self.departments.build department: "Test Dept", production_id: self.id
end
end
每个部门都有很多职位。我也想为部门创造职位。如何将新职位与该模型中的部门相关联?
答案 0 :(得分:2)
有两种方法:
#app/models/project.rb
class Project < ActiveRecord::Base
has_many :departments
accepts_nested_attributes_for :departments
before_create :set_department
private
def set_department
self.departments.build department: "Test"
end
end
#app/models/department.rb
class Department < ActiveRecord::Base
has_many :positions
accepts_nested_attributes_for :positions
before_create :set_positions
private
def set_positions
self.positions.build x: y
end
end
......或......
#app/models/project.rb
class Project < ActiveRecord::Base
has_many :departments
accepts_nested_attributes_for :departments, :projects
before_create :set_departments
private
def set_departments
dpt = self.departments.build department: "Test"
dpt.positions << Position.new position: "Admin"
dpt.positions << Position.new position: "Tester"
end
end
-
您还可以在一行上声明多个嵌套属性:
accepts_nested_attributes_for :departments, :positions
答案 1 :(得分:1)
如果我理解你的问题,你可能会在你的部门模型中做这样的事情:
after_create { self.positions.create! }
虽然这可能是一个有问题的方法。使用ActiveRecord回调创建这样的记录(这就是为我们提供了after_create)可以使你的整个应用程序变得非常脆弱。例如,如果你这样做,你将永远无法建立没有相关职位的部门。也许有一天你需要这样做。
即使它不是您问题的确切答案,我建议您在服务对象中创建这些关联模型,或者至少在控制器代码中创建。
答案 2 :(得分:0)
您可以使用以下内容添加新职位:
Project.first.positions << Position.create(:foo => 'foo', :bar => 'bar')
或
position = Position.create(:foo => 'foo', :bar => 'bar')
Department.first.positions << position
Project.first.positions << position
显然“.first”仅用于说明,您可以将<<
表示法用于任何部门或项目实例。
再看一遍,它似乎非常适合多态关联。
class Position < ActiveRecord::Base
belongs_to :positioned, polymorphic: true
end
class Project < ActiveRecord::Base
has_many :positions, as: :positioned
end
class Department < ActiveRecord::Base
has_many :positions, as: :positioned
end
在您的迁移中:
create_table :positions do |t|
...
t.integer :positioned_id
t.string :positioned_type
...
end
可能有更适合为您的应用命名的方法,但这是一般的想法。