Rails 3.1: accepts_nested_attributes_for и has_one - не сработает? - PullRequest
8 голосов
/ 08 октября 2011

Я пытаюсь использовать accepts_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" с консоли, поэтому я знаю, что ассоциации установлены правильно.

У меня есть две формы на странице редактирования пользователя. Тот, который обновляет основные пользовательские атрибуты (и работает нормально, и не показан ниже), а затем этот, который позволяет пользователю обновлять атрибут модели местоположения, называемый "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 "/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. Есть сообщение "COMMIT", но без предшествующей строки обновления и без ошибки. Например, если вы попытаетесь зафиксировать защищенный атрибут, в этот момент вы получите сообщение об ошибке «Вы не можете массово назначить ...».

  2. Параметры выглядят неправильно для меня. Бит "location" вложен, как я и ожидал, но я также ожидал, что это будет вложенный в хэш "user", что-то вроде этого:

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

Не думаю, что я здесь совершенно глупый. Я что-то упускаю действительно очевидное? Я попытался добавить дополнительные скрытые поля в мою форму, то есть идентификатор пользователя, и затем я получил хеш пользователя, но на том же уровне, что и хеш "location", а не как его родитель, как я ожидал!

Также, если это поможет, вот мое обновление в моем UsersController:

обновление по умолчанию @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

конец

и вот что есть в моем файле route.rb (хотя я не думаю, что это актуально):

resources :users do
  resource :location
end

Любая помощь приветствуется. Если я не решу это, ноутбук выйдет в окно .... Спасибо.

Ответы [ 2 ]

11 голосов
/ 08 октября 2011
<%= fields_for(@user.location) do |location_fields| %>

Это ваша проблема.Вам действительно нужно «вложить» fields_for внутри вашей формы, например:

<% f.fields_for(@user.location) do |location_fields| -%>
5 голосов
/ 08 октября 2011

Попробуйте вместо этого

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

Вместо того, чтобы давать ему сам объект, сообщите рельсам, какую ассоциацию вы хотите, чтобы он загружал для

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...