2013-06-12 12 views
7

私は複雑なネストされたフォームを管理するために次のフォームオブジェクトを持っています。フォームオブジェクトを使用すると、編集アクションと更新アクションはどのように処理する必要がありますか?

フォーム

= simple_form_for(@profile_form, :url => profiles_path) do |f| 
    ... 

ルート

resources :profiles 

コントローラ

class ProfilesController < ApplicationController 
    def new 
    @profile_form = ProfileForm.new 
    end 

    def edit 
    @profile_form = ProfileForm.new(params[:id]) 
    end 

    def create 
    @profile_form = ProfileForm.new 
    if @profile_form.submit(params[:profile_form]) 
     redirect_to @profile_form.profile, notice: 'Profile was successfully created.' 
    else 
     render action: "new" 
    end 
    end 

    def update 
    @profile_form = ProfileForm.new(params[:id]) 
    if @profile_form.submit(params[:profile_form]) 
     redirect_to @profile_form.profile, notice: 'Profile was successfully updated.' 
    else 
     render action: "edit" 
    end 
    end 
end 

フォームオブジェクト

class ProfileForm 
    include ActiveModel::Validations 
    include ActiveModel::Conversion 
    extend ActiveModel::Naming 

    def initialize(profile_id = nil) 
    if profile_id 
     @profile = Profile.find(profile_id) 
     @person = profile.person 
    end 
    end 
    ... 
    def submit(params) 
    profile.attributes = params.slice(:available_at) 
    person.attributes = params.slice(:first_name, :last_name) 

    if valid? 
     profile.save! 
     person.save! 
     true 
    else 
     false 
    end 
    end 
    def self.model_name 
    ActiveModel::Name.new(self, nil, "Profile") 
    end 

    def persisted? 
    false 
    end 
end 

しかし、今、私はこのフォームにcreateアクションを使用してオブジェクトを編集していたときに呼び出されます。 このフォームをどのようにリファクタリングする必要がありますか?下のコードupdateは別のProfileオブジェクトを作成します。

答えて

6

simple_form_forは、そのジョブを実行するために内部form_forを使用しています。 form_forは、メソッドpersisted?を使用して、オブジェクトがすでにデータベースに保持されているかどうかを判断します。それはすでに、オブジェクトを更新するをPUT 方法でフォームを生成しますform_forを永続化された場合、それ以外の場合は、新しいオブジェクトを作成するための方法POSTでフォームを生成します。したがって、フォームオブジェクトのためにpersisted?メソッドを実装する必要があります。あなたはこのようにそれを実現することができます。

class ProfileForm 
    # ... 
    def persisted? 
    @person.persisted? && @profile.persisted? 
    end 
    # ... 
end 

更新場合@personは、私はあなたが@profileに関連付けるために新しいPersonを作成したとし、すなわちProfileに関連付けられPersonはありません、nilです。この場合、それはProfileFormpersisted?があると仮定しても安全である限り、少なくとも@profileとしてので、persisted?です:

class ProfileForm 
    # ... 
    def persisted? 
    @profile.persisted? 
    end 
    # ... 
end 

更新は、エラーを回避するにはundefined local variable or method `id'あなたがProfileFormためid方法を定義する必要があり、このように:

class ProfileForm 
    # ... 
    def id 
    @profile.id 
    end 
    # ... 
end 
+0

さて、ありがとう、ありがとう。しかし、どのように、フォームのURLを変更する: '' = simple_form_for(@profile_form、:URL => profiles_path)やる| F | ''そして、私はエラーが表示さ:#のための ''未定義のローカル変数やメソッド 'IDを」 '' – tomekfranek

+0

@personがnilの場合はどうなりますか? – tomekfranek

+0

'' to_param''メソッドを追加した後も同じエラーが表示されます。問題はURLであるように見えます。 – tomekfranek

0
replace 

    = simple_form_for(@profile_form, :url => profiles_path) do |f| 

    with 

    = simple_form_for(@profile_form, :url => {:controller => "profiles"}) do |f| 
+1

いいえ、何も変更されていません。フォームURLはまだです:action: ''/profiles''メソッド: '' post'' – tomekfranek

関連する問題