2

我正在尝试向 Rails 脚手架控制器发送一个 POST 请求,该控制器包含一个嵌套数组,表示需要创建并与新创建的父级关联的记录。

下面是一些 JSON 示例:

{
    "plan_id":3,
    "weight":60,
    "exercise_sets": [
        {
            "created_at":"2012-06-13T14:55:57Z",
            "ended_at":"2012-06-13T14:55:57Z",
            "weight":"80.0",
            "repetitions":10,
            "exercise_id":1
        }
    ]
}

..和我的模型..

class Session < ActiveRecord::Base
  has_many :exercise_sets, :dependent => :destroy
  has_many :exercises, :through => :exercise_sets
end

class ExerciseSet < ActiveRecord::Base
  belongs_to :exercise
  belongs_to :session
end

我正在尝试的可能吗?

4

2 回答 2

5

这当然不是不可能的,尽管您可能需要稍微改变一下参数命名。

当您将上面的 JSON 传递给控制器​​时,它要么作为参数传递给构造函数:

Session.new(params[:session])

或者传递给持久会话实例上的 #update_attributes 方法:

@session = Session.find(params[:id])
@session.update_attributes(params[:session])

构造函数和#update_attributes 方法都将诸如“plan_id”之类的参数转换为分配方法调用。那是,

@session.update_attributes(:plan_id => "1")  

变成(在#update_attributes 方法内):

@session.plan_id = "1"

因此,这适用于您的 plan_id 和 weight 属性,因为您同时拥有 #plan_id= 和 #weight= setter 方法。您还有一个由has_many :exercise_sets. 但是,#exercise_sets= 方法需要练习集对象,而不是练习集属性

Rails 能够通过#accepts_nested_attributes_for 类方法来做你想做的事情。试试这个:

class Session < ActiveRecord::Base
  has_many :exercise_sets, :dependent => :destroy
  has_many :exercises, :through => :exercise_sets

  accepts_nested_attributes_for :exercise_sets
end

这会为您设置(元程序)#exercise_sets_attributes= 方法。因此,只需将您的 JSON 修改为:

{
    "plan_id":3,
    "weight":60,
    "exercise_sets_attributes": [
        {
            "created_at":"2012-06-13T14:55:57Z",
            "ended_at":"2012-06-13T14:55:57Z",
            "weight":"80.0",
            "repetitions":10,
            "exercise_id":1
        }
    ]
}

更多信息:http ://api.rubyonrails.org/classes/ActiveRecord/NestedAttributes/ClassMethods.html

于 2012-06-25T19:59:13.683 回答
0

完全有可能,您只需在Session模型中添加以下行:

  accepts_nested_attributes_for :exercise_sets, :reject_if => lambda { |a| a[:exercise_id].blank? }, :allow_destroy => true

现在,当您的控制器这样做时Session.new(params[:session]),Rails 将构建(或更新)Session 相关的ExerciceSet(S)。

请查看:reject_if条款。这就是您定义将创建哪些记录以及不创建哪些记录的地方。

这是基础知识,但 Ryan Bates 在此截屏视频中完美(一如既往)解释了嵌套模型形式。

于 2012-06-25T19:59:44.513 回答