如何将属性保存到has_many:通过连接表,没有要构建的现有记录

时间:2013-11-30 01:59:11

标签: ruby-on-rails ruby-on-rails-3 has-many-through

我有一个表单,使用accepts_nested_attributes_for

创建一个新的子记录和一个新的父记录

儿童和家长有has_many :through这样的关联:

class Child < ActiveRecord::Base
   has_many :relationships
   has_many :parents, through: :relationships
   accepts_nested_attributes_for :parents
   accepts_nested_attributes_for :relationships, allow_destroy: true
end

class Parent < ActiveRecord::Base
   has_many :relationships
   has_many :children, through: :relationships
end

class Relationship < ActiveRecord::Base
   belongs_to :child
   belongs_to :parent
   accepts_nested_attributes_for :parents

   #has :schedule attribute
end

我想同时在Relationships中设置schedule属性,并且不能使用accepts_nested_attributes_for,因为我正在操纵控制器中的某些数据以确定schedule之前的对象节省。

堆栈溢出有很多答案可以通过预先存在的父记录完成此操作,但是我找不到任何以前没有关联的情况。

我尝试在模型中使用after_create回调执行此操作,但无法访问params并且已经读过这样做无论如何都是错误的过程。 (Rails How to pass params from controller to after_save inside model)。

理想情况下,我希望在创建关系记录的同一数据库调用中设置schedule以及child_idparent_id

对此有任何帮助都很棒,谢谢

更新

控制器截至原始帖子

def new
  @child = Child.new
end

def create
  @child = Child.new(params[:child])
  schedule = build_schedule(params)
  # Need to save schedule to @child.relationship[0].schedule somehow
  if @child.save!
    redirect_to admins_path
  else
    render 'new'
  end
end

private

def build_schedule(params)
  # works with params[:mon, :tue, :wed, :thu, :fri] to return a schedule object.
end

使用Ryan Bates' nested form helper构建parent。这是它的构建线:

module ApplicationHelper
  def link_to_add_fields(name, f, association)
    new_object = f.object.send(association).klass.new
    ...
  end
end

我根本没有构建relationship,据我所知,它是由rails构建的。

尝试 Danny Van Hoof的建议@child.relationships[0].schedule =我得到undefined method schedule=' for nil:NilClass,因为没有任何关系。

如果我事先使用newcreate@child.relationship.build操作中建立关系,我会保存2条关系记录:

relationships table

我构建的那个已保存schedule但没有parent_id(parental_group_id) 第二个记录是一个神奇的构建,并且具有正确的ID但没有schedule

现在通过添加

来尝试 Rick Peck的建议
def params
    params.require(:child).permit(relationships_attributes: [:schedule])
    # tried with and without `parents_attributes`
end 

我在stack level too deep行上收到params.require错误。我也不完全明白这是做什么的。 (我对铁轨很新)

感谢您的帮助!

2 个答案:

答案 0 :(得分:1)

我在我的一个网站上有类似的构造,它工作正常,除了我(翻译成你的例子)

attr_accessible :relationships_attributes
accepts_nested_attributes_for :relationships, allow_destroy: true

在我的关系模型中,我然后使parent_id可访问

这允许在控制器中执行类似

的操作
@child.relationships[0].schedule = ...

甚至在拯救孩子之前

或者,或者,在输入父详细信息时立即从您的视图设置计划

如果不清楚,请给我发表评论!

答案 1 :(得分:1)

首先,您的accepts_nested_attributes_for必须包含join model,然后将数据传递到其他模型,如下所示:

class Child < ActiveRecord::Base
   has_many :relationships
   has_many :parents, through: :relationships

   accepts_nested_attributes_for :relationships
end

class Parent < ActiveRecord::Base
   has_many :relationships
   has_many :children, through: :relationships
end

class Relationship < ActiveRecord::Base
   belongs_to :child
   belongs_to :parent

   #attr_accessor :schedule ?
   accepts_nested_attributes_for :parents
end

#app/controllers/child_controller.rb
def new
    @child = Child.new
    @child.relationships.build.parents.build
end

private
def params
    params.require(:child).permit(relationships_attributes: [:schedule, parents_attributes: [:variable-1, :variable-2]])
end

这会将所需数据传递到relationships,然后传递到parents。当您处理schedule模型

中的变量时,可以处理relationships