2012-10-26 8 views
5

私はルビーとレールが新しく、できるだけコーディングの標準と慣習に従っていきたいので、悪い習慣はありません。コースと場所の2つのモデルがあります。コースは1つの場所にしか属しません。ロケーションは2つ以上のコースで共有できるため、場所には数多くのコースがあります。モデルとアソシエーションをレールに保存する方法を理解するのに苦労しています

コースを作成するときに、IDで見つかった場所が既に存在する可能性があります。または、場所がまだ存在しない場合は、新しい場所レコードを作成する必要があります。 My 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です。要求ポスト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. 、このコードはとてもエレガントに見えないをするJavaScript 。それを考慮する良い方法はありますか?
  2. Location.createで例外が発生した場合でも、@ course.saveは呼び出されますか? Location.create!を使用する必要がありますか?
  3. 同様に、エラーがLocationモデルにあったとしても、検証エラーは@ course.errorsになりますか?エラーをクライアントに返すために例外から救助する必要がありますか?

ご協力いただきありがとうございます。

答えて

2

について

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 

以上にあなたが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番目の質問については、コード内であなたがLocation.create(またはLocation.find)は例外が発生した場合(彼らが最初に起こるので)それは@course.saveと呼ばれることはありません持っているよう。しかし、上記のようにコード化したのは、saveが呼び出されたときに、コード内の同じポイントで例外が発生し、その時点で関連付けも保存されます。

+0

ありがとうございます!私はこのようなものに向かって傾いていたが、私は寒い足を持っていた。例外処理に関する疑念を確認しました。私の期待に影響を与える可能性のある何かがシーンの裏で起こっているかどうかは分かりませんでした。コースモデルに 'accepts_nested_attributes_for:location'を追加する必要がありますか? – glevine

+0

あなたは大歓迎です。 AFAIKを使わない場合は、場所の属性を明示的に設定しているので、これを行うには 'accepts_nested_attributes_for:location'を追加する必要はありません。ただし、ネストされた属性があれば、 '@course = Course.new(params [:course])'だけですべてを初期化でき、自動的に 'location'属性が設定されると思います。 'id'が設定されているときに動作するかどうかは不明ですが、テストしていません。 –

+0

私はいくつかのテストを書く必要がありますが、一度私は自分の所見にコメントを追加します。私の懸念は、 'id'がネストされた場所に設定されているが、他のフィールドはすべて空であれば、実際には一致する場所の属性を更新し、空のフィールドが有効であると仮定してそれらを設定し、記録。その結果、ロケーションレコードのデータが消去されます。しかし、私は助けができませんが、レールは何をすべきかを知るには十分にスマートであると考えることはできません。私が言ったように、私はそれが実際にどのように動作するかを知ったら、私は再び返信します。 – glevine

1

は、コントローラnested_attributes

+0

返信いただきありがとうございます! find_or_initialize_by_idを使用するのではなく、これを行う利点は何ですか?入れ子になったモデルについてもっと知る必要があります。私はこの点をネスティングに関連させて接続していなかったと思います。 – glevine

関連する問題