2011-10-08 13 views
8

Próbuję użyć accepts_nested_attributes_for na has_one modelu stowarzyszenia, a uzyskanie absolutnie nigdzie :-(Rails 3.1: accepts_nested_attributes_for i has_one association - nie zadziała?

mam dwa modele, użytkownik i lokalizację Użytkownik ma jedną lokalizację.

class User < ActiveRecord::Base 
    # current location 
    has_one :location, :dependent => :destroy 
    accepts_nested_attributes_for :location 
end 

class Location < ActiveRecord::Base 
    belongs_to :user 
end 

Mogę zapisać zmiany w modelu przy użyciu User.find(1).location.current_location_text = "blah" z konsoli, więc wiem, że powiązania są poprawnie skonfigurowane

Mam dwa formularze na stronie edycji użytkownika, jeden aktualizuje główne atrybuty użytkownika (i działa dobrze i nie pokazane poniżej), a następnie ten, który pozwala użytkownikowi zaktualizować att ribute modelu lokalizacji, o nazwie "current_location_text":

<%= form_for(@user) do |f| %> 
    <%= fields_for(@user.location) do |location_fields| %> 
     <%= location_fields.label :current_location_text, 'Current Location' %> 
     <%= location_fields.text_field :current_location_text, :placeholder => 'Road, City or Postcode' %> 
    <% end %> 

    <%= f.submit "Update Current Location" %> 
<% end %> 

To nie działa. Jestem nieco zdezorientowany, ponieważ parametry wysyłane przez formularz wyglądają niepoprawnie. Po wysłaniu formularza, to w dzienniku:

Started PUT "https://stackoverflow.com/users/1" for 127.0.0.1 at 2011-10-08 00:28:05 +0100 
    Processing by UsersController#update as HTML 
    Parameters: {"utf8"=>"✓", "authenticity_token"=>"YdTAsXwEvRgXIqri+jfx3dLlYG2XWQTuYkgLDsO/OJw=", "location"=>{"current_location_text"=>"E14 8JS"}, "commit"=>"Update Current Location", "id"=>"1"} 
    User Load (10.3ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 LIMIT 1 
    User Load (5.3ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = ? LIMIT 1 [["id", "1"]] 
    SQL (4.4ms) BEGIN 
    (2.5ms) COMMIT 
Redirected to http://localhost:3000/users/1 

dwie rzeczy, które mogę znaleźć dziwaczne o tym:

  1. Jest komunikat „commit”, ale bez poprzedzającego ciąg aktualizacji i żaden błąd. na przykład, jeśli próbowałeś popełnić chroniony atrybut, otrzymasz komunikat o błędzie "nie możesz przydzielić masy ..." w tym momencie.

  2. Params wyglądają źle do mnie. „Location” bit jest zagnieżdżony jak będę oczekiwać, ale Chciałbym również spodziewać, że jest to zagnieżdżona wewnątrz „user” hash, coś takiego:

    {"utf8"=>"✓", "authenticity_token"=>"YdTAsXwEvRgXIqri+jfx3dLlYG2XWQTuYkgLDsO/OJw=", "user"=>{"location"=>{"current_location_text"=>"E14 8JS"}, "commit"=>"Update Current Location", "id"=>"1"}} 
    

nie sądzę Jestem tutaj zupełnie głupi. Czy brakuje mi czegoś naprawdę oczywistego? Próbowałem dodać do mojego formularza dodatkowe ukryte pola, tj. Identyfikator użytkownika, a następnie otrzymałem skrót użytkownika, ale na tym samym poziomie co skrót "lokalizacji", a nie jako jego rodzic, jak się spodziewałam!

Także, jeśli to pomoże, oto moja zmiana w moim UsersController:

def aktualizować @user = User.find (params [: id])

if @user.update_attributes(params[:user]) 
    redirect_to current_user, :notice => 'User was successfully updated.' 
else 
    render :action => "edit" 
end 

końcowych

i oto co jest w moich routes.rb (chociaż nie sądzę, że jest to istotne):

resources :users do 
    resource :location 
end 

Każda pomoc doceniona. Jeśli tego nie rozwiążę, laptop wyjdzie przez okno ... Dzięki.

Odpowiedz

11
<%= fields_for(@user.location) do |location_fields| %> 

To jest twój problem.Trzeba rzeczywiście „gniazdo” THE fields_for wewnątrz formy, tak:

<% f.fields_for(@user.location) do |location_fields| -%> 
+0

Dokumentacja referencyjna? Wszystko, co widzę, to dokumenty mówiące, że '<% -%>' ma zajmować się końcowymi białymi znakami. (http://api.rubyonrails.org/classes/ActionView/Base.html) – 0112

+0

Aby wyjaśnić, problem polegał na 'fields_for' kontra' f.fields_for'. '-%>' było po prostu nawykiem. –

5

Spróbuj zamiast

<%= f.fields_for :location do |location_fields| %> 

Zamiast nadając mu sam obiekt, powiedz szyn co skojarzenie chcesz mieć go załadować do

+0

Dzięki - I rzeczywiście potrzebne, aby to zrobić też uważam, że to dziwne, że za pomocą obiektu w fields_for deklaracji nie działa. – DaveStephens

+0

Dla każdego, kto używa klejnotu Judge do sprawdzania poprawności inline: otrzymasz błędy za pomocą tej metody. Użyj @ user.location zamiast symbolu, ponieważ Judge musi odwoływać się do obiektu. – bradleygriffith