我有3个模型:雇主,合作伙伴和合作。
作为雇主,我想在我的合作伙伴模型和我的协作模型中添加记录,以便能够指示合作伙伴和雇主之间的协作。因此,我的数据库/表格中有以下列。
模型
class Employer < ActiveRecord::Base
has_many :collaborations
has_many :partners, :through => :collaborations
end
class Partner < ActiveRecord::Base
has_many :collaborations
has_many :employers, :through => :collaborations
accepts_nested_attributes_for :collaborations
end
class Collaboration < ActiveRecord::Base
belongs_to :employer
belongs_to :partner
end
表格
Collaborations
employer_id:integer
partner_id:integer
tarive:string
Partners
added_by:integer
name:string
因为我希望能够在1个表单中添加合作伙伴/协作,所以我使用嵌套表单。所以我可以一次性添加合作伙伴(名称等)和协作(tarive等)。
我的(simple_form)表单看起来像这样(我有named_space资源)。 为了减少混乱,我删除了尽可能多的HTML mark_up,这不是问题。
表格
/视图/雇主/伙伴/ _form
= simple_form_for [:employer, @partner], html: { multipart: true } do |f|
Partner
= f.input :name, input_html: { class: 'form-control' }
= f.simple_fields_for :collaborations do |ff|
Tarive
= ff.input :tarive, input_html: { class: 'form-control' }
= f.button :submit, "Save"
我的控制器看起来像
class Employer::PartnersController < ActionController::Base
def new
@partner = Partner.new
@partner.collaborations.build
end
def create
@partner = Partner.new(partner_params)
@partner.collaborations.build
@partner.added_by = current_employer.id
@partner.collaborations.employer_id = current_employer.employer_id
@partner.collaborations.partner_id = @partner.id
@partner.collaborations.added_by = current_employer.id
if @partner.save
redirect_to employer_partner_path(@partner), notice: "Succes!"
else
render 'new'
end
end
def partner_params
params.require(:partner).permit(:id, :name, collaborations_attributes: [:id, :employer_id, :partner_id, :tarive])
end
end
问题
我遇到的问题是这个问题。属性很好地分配并添加到模型中。但我想添加一个employer_id
,我在current_employer.employer.id
(设计)中添加了@partner.added_by = current_employer.id
。我不想使用隐藏的表单,只是为了避免这个问题。
我指定了父母&#39;模型总是像@partner.collaborations.employer_id = current_employer.employer_id
一样,效果很好。
当我使用时:
@partner.collaborations.employer_id
我收到错误,说current_employer.employer_id
为空。
问题
如何在我的控制器#create中为nested_form(Collaboration)分配变量?
或者更具体地说:我如何将@partner.collaborations.employer_id
分配给docx
?
答案 0 :(得分:2)
有几种方法:
- 合并参数
- 处理对象,而不是外键
醇>
就个人而言,我觉得你的create
方法看起来效率很低。实际上,您应该知道关联逻辑的fat model skinny controller
- 大多数应保留在模型中。
可以使用以下方法进行改进:
#app/controllers/employers/partners_controller.rb
class Employers::PartnersController < ApplicationController
def new
@partner = current_employer.partners.new #-> this *should* build the associated collaborations object
end
def create
@partner = current_employer.partners.new partner_params
@partner.save ? redirect_to(employer_partner_path(@partner), notice: "Succes!") : render('new')
end
private
def partner_params
params.require(:partner).permit(:id, :name, collaborations_attributes: [:tarive]) #when dealing with objects, foreign keys are set automatically
end
end
这将允许您使用:
#app/views/employers/partners/new.html.erb
= simple_form_for @partner do |f| #-> @partner is built off the current_employer object
= f.input :name
= f.simple_fields_for :collaborations do |ff|
= ff.input :tarive
= f.submit
......和模特:
#app/models/partner.rb
class Partner < ActiveRecord::Base
belongs_to :employer, foreign_key: :added_by
has_many :collaborations
has_many :employers, through: :collaborations
accepts_nested_attributes_for :collaborations
end
#app/models/collaboration.rb
class Collaboration < ActiveRecord::Base
belongs_to :employer
belongs_to :partner
belongs_to :creator, foreign_key: :added_by
before_create :set_creator
private
def set_creator
self.creator = self.employer_id #-> will probably need to change
end
end
#app/models/employer.rb
class Employer < ActiveRecord::Base
has_many :collaborations
has_many :employers, through: :collaborations
end
这可能不使您能够设置tarive
,但是如果您减少模型中的手动声明,我们应该能够看到对它进行排序。
您需要做的主要是减少控制器中的代码。你是非常具体的,因此,你遇到的问题就像你提到的那样。