2011-10-08 68 views
8

我試圖在HAS_ONE關聯模型使用accepts_nested_attributes_for,並獲得絕對無處:-(Rails 3.1:accepted_nested_attributes_for和has_one關聯 - 不起作用?

我有兩個型號,用戶和位置的用戶有一個位置:

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 

我可以通過從控制檯使用User.find(1).location.current_location_text = "blah"保存對模型的更改,所以我知道關聯設置正確。

我在編輯用戶頁面上有兩種形式:一種更新主要用戶屬性(並且可以正常工作,沒有在下面顯示),然後是允許用戶更新att的那個定位模型的ribute,被稱爲 「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 %> 

這是行不通的。由於表單發送的參數看起來不正確,我有點困惑。當表單提交,這是在日誌中:

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 

兩件事情,我覺得離奇一下:

  1. 有「提交」的消息,但沒有前面的更新字符串,沒有錯誤。例如,如果您嘗試提交受保護的歸因文件,那麼您會在此時收到「您無法批量分配......」錯誤消息。

  2. PARAMS看起來不對我。 「位置」位被嵌套爲我所期待的,但我還希望這是一個嵌套的「用戶」散列內,像這樣:

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

我不認爲我在這裏完全愚蠢。我錯過了真正明顯的東西嗎?我嘗試添加額外的隱藏字段到我的表單,即用戶ID,然後我得到用戶散列,但在與「位置」散列相同的級別,而不是我所期望的父級!

此外,如果有幫助,這是我UsersController內我更新:

高清更新 @user = User.find(PARAMS [:編號])

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

和這裏的有什麼在我的routes.rb(雖然我認爲它不相關):

resources :users do 
    resource :location 
end 

任何幫助表示讚賞。如果我沒有解決這個問題,筆記本電腦正在走出去...... 謝謝。

回答

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

這是你的問題。你需要真正的「鳥巢」你的表格裏面的fields_for,就像這樣:

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

文檔參考?我只能看到文檔說的是'<% -%>'是爲了處理尾隨的空白。 (http://api.rubyonrails.org/classes/ActionView/Base.html) – 0112

+0

只是爲了澄清,問題是'fields_for'與'f.fields_for'。 ' - %>'只是習慣。 –

5

試試這個

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

而不是給它的對象本身,告訴你,你有什麼關聯軌它加載

+0

謝謝 - 我確實需要就此別過,我覺得很奇怪的是,在fields_for聲明使用對象不起作用。 – DaveStephens

+0

對於任何使用Judge gem進行內聯驗證的人員:您將使用此方法獲得錯誤。使用@ user.location而不是符號,因爲Judge需要引用該對象。 – bradleygriffith