5

我是 ruby​​ 和 rails 的新手,我想尽可能地遵循编码标准和约定,所以我不会养成任何坏习惯。我有两个模型:课程和位置。一门课程属于一个位置,因为一门课程只能有一个位置。一个位置有多个课程,因为一个位置可以由多个课程共享。

创建课程时,可能已经存在通过其 ID 找到的位置。或者该位置可能还不存在,在这种情况下,必须创建一个新的位置记录。我的课程控制器具有以下创建操作。

def create
  @course = Course.new(params[:course])

  if params[:course][:location][:id].blank?
    @course.location = Location.create(params[:course][:location])
  else
    @course.location = Location.find_by_id(params[:course][:location][:id])
  end

  @course.save

  respond_with @course
end

请注意,这是一个仅使用 JSON 响应的 REST API。发出请求的 javascript 以与 GET 请求返回的相同格式发布 JSON 数组

{
  "course":
  {
    "title":"US History",
    "credits":"3",
    "max_students":"100",
    "location":
    {
      "id":"",
      "building":"Freedom Hall",
      "room":"301"
    }
  }
}

or

{
  "course":
  {
    "title":"US History",
    "credits":"3",
    "max_students":"100",
    "location":
    {
      "id":"12", # this is the only difference
      "building":"Freedom Hall",
      "room":"301"
    }
  }
}
  1. 与我读过的所有示例相比,这段代码看起来并不那么优雅。有没有更好的方法来分解它?
  2. 如果 Location.create 引发异常,还会调用 @course.save 吗?我需要使用 Location.create! 吗?
  3. 同样,验证错误是否会出现在 @course.errors 中,即使错误出现在 Location 模型上?我是否需要从异常中解救,以便将错误返回给客户端?

非常感谢您的任何帮助!

4

2 回答 2

2

您可以使用find_or_initialize_by_id. 这应该有效:

def create
  @course = Course.new(params[:course])
  @course.location = Location.find_or_initialize_by_id(params[:course][:location][:id],
                                                       params[:course][:location])
  @course.save
  respond_with @course
end

关于您的第二个问题,在您的代码中,如果(或)引发异常(因为它们会首先发生) ,@course.save则不会调用它。但是,按照我上面的编码方式,异常会发生在代码中的同一点,当被调用时,关联也会被保存。Location.createLocation.findsave

于 2012-10-26T07:17:16.690 回答
1

试试这个,在你的控制器中

def new
  @course = Course.new 
  @location = @course.location.build # if one..many relationship
  @location = @course.build_location # if one..one relationship
end

def create
 @course = Course.new(params[:course])
 if @course.save
   respond_with @course
 else
   render :action => "new"
 end
end

更多关于nested_attributes

于 2012-10-26T07:15:13.717 回答