2013-06-12 13 views
7

Mam następujący obiekt formularza do zarządzania skomplikowanym formularzem zagnieżdżonym.Jak powinienem obsługiwać akcję edycji i aktualizacji, gdy używam obiektu formularza?

Forma

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

Trasy

resources :profiles 

sterownika

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 

Forma obiektu

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 

Ale teraz, kiedy jestem edycji obiektu za pomocą tego formularza create działań jest tzw. Jak powinienem zmienić ten formularz? Kod poniżej na update tworzy kolejny obiekt profilu.

Odpowiedz

6

simple_form_for używa form_for wewnętrznie do wykonania swojej pracy. form_for używa metody persisted? do decydowania, czy obiekt jest już utrwalony w bazie danych, czy nie. Jeśli jest już utrwalony, form_for wygeneruje formularz z metodą PUT, aby zaktualizować obiekt, w przeciwnym razie wygeneruje formularz z metodą POST, aby utworzyć nowy obiekt. Dlatego musisz zaimplementować metodę persisted?, aby utworzyć obiekt. można wdrożyć go tak:

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

Aktualizacja W przypadku @person jest nil, to znaczy nie ma Person związane z Profile, przypuszczam, by utworzyć nową Person skojarzyć do @profile. W tym przypadku jest to bezpieczne założenie, że ProfileForm jest persisted? dopóki przynajmniej @profile jest persisted?, a więc:

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

Aktualizacja Aby uniknąć błędu undefined local variable or method `id' trzeba zdefiniować metodę id dla ProfileForm, tak:

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

Ok, teraz rozumiem, dzięki. Ale jak zmienić adres URL formularza: '' = simple_form_for (@profile_form,: url => profiles_path) do | f | '' I pojawia się błąd: '' niezdefiniowana zmienna lokalna lub metoda 'id 'dla # '' – tomekfranek

+0

A co, jeśli @person jest zerowe? – tomekfranek

+0

Po dodaniu metody '' to_param'' nadal mam ten sam błąd. Wygląda na to, że problem dotyczy adresu 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

Nie, nic się nie zmieniło. URL formularza jest nadal: akcja: metoda ''/profiles'': '' post'' – tomekfranek

Powiązane problemy