5

私は ruby​​ と rails に不慣れで、コーディングの標準と規則にできる限り従いたいので、悪い習慣を身につけないようにしています。Course と Location の 2 つのモデルがあります。コースは 1 つの場所にのみ属することができるため、コースは場所に属します。場所は複数のコースで共有される可能性があるため、場所には多くのコースがあります。

コースを作成するとき、その ID で見つかったロケーションがすでに存在している場合があります。または、ロケーションがまだ存在しない可能性があります。その場合、新しいロケーション レコードを作成する必要があります。私の Course コントローラーには、次の作成アクションがあります。

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. 同様に、エラーが Location モデルにあったとしても、検証エラーは @course.errors で終了しますか? エラーをクライアントに返すことができるように、例外からレスキューする必要がありますか?

いろいろと助けてくれてありがとう!

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

あなたの2番目の質問に関して、あなたのコードでは、 (または)が例外を発生させた@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 に答える