Rails 3.2: ассоциация nested_attributes и has_one в двух разных формах

Я использую accepts_nested_attributes_for в модели ассоциации has_one.

У меня есть две модели, пользователь и профиль. У пользователя есть один профиль:

class User < ActiveRecord::Base
  attr_accessible :name, :email,:profile_attributes
  has_one :profile
  accepts_nested_attributes_for :profile
end

class Profile < ActiveRecord::Base
  attr_accessible :avatar
  belongs_to :user
  mount_uploader :avatar, AvatarUploader
end

У меня есть две формы на странице редактирования пользователя. Тот, который обновляет основные атрибуты пользователя (работает нормально и не показан ниже), а затем тот, который позволяет пользователю загружать аватар:

<%= form_for @user, :html => {id: 'avatar_form' ,:multipart => true } do |f| %>
  <%= f.fields_for :profile do |builder| %>
  <%= builder.file_field :avatar %>
  <% end %>
  <%= f.submit %>
<% end %>

Эта отправка не работает, я получаю это сообщение об ошибке:

NoMethodError в UsersController#update

неопределенное имя метода для nil:NilClass

Мой код UsersController для обновления:

def update
  @user = current_user
  if @user.update_attributes(params[:user])
    redirect_to home_path
  else
    render 'edit'
  end
end

И параметры:

{"utf8"=>"✓",
"_method"=>"put",
"authenticity_token"=>"YTpGnj9uIpybDAgf4c6pxMydY15ga5GZ++FBMe/6dV4=",
"user"=>{"profile_attributes"=>{"avatar"=>#<ActionDispatch::Http::UploadedFile:0x2303e08 @original_filename="test.jpg",
@content_type="image/jpeg",
@headers="Content-Disposition: form-data; name=\"user[profile_attributes][avatar]\";  filename=\"test.jpg\"\r\nContent-Type: image/jpeg\r\n",
"id"=>"3"}},
"commit"=>"Upload",
"id"=>"1"}

Любая помощь будет оценена по достоинству. Спасибо!!


person Sebas    schedule 23.11.2012    source источник
comment
Ваш пользователь вошел в систему? Я имею в виду, что если current_user равно нулю, вы получите это сообщение об ошибке, так что это не может работать, когда никто из пользователей не вошел в систему.   -  person alony    schedule 23.11.2012
comment
Да, пользователь вошел в систему, у меня есть before_filter :signed_in_user, только: [:home, :update, :edit].   -  person Sebas    schedule 23.11.2012
comment
Решил! У меня были проблемы с авторизацией в папке tmp, поменял на def cache_dir "#{Rails.root}/tmp/uploads" end   -  person Sebas    schedule 25.11.2012


Ответы (2)


Добавьте в свой пользовательский контроллер

def new
  @user = User.new
  @user.profile.build
  #or
  #@user.build_profile

end

Чтобы лучше понять, что происходит, попробуйте добавить гем «better_errors» в свой Gemfile.

gem "better_errors"

вы получите своего рода консоль, где вы можете ввести

@user

и на выходе вы получите (nil или obj). Если ноль, вы определенно подделываете эту строку в новом действии.

@user = User.new

Если вы используете divise для auto. поддержан, перепишите контроллер, как здесь Переопределить контроллер регистрации устройств

person Andrey Yasinishyn    schedule 06.05.2013

@Andrey Что касается отношения has_one, @user.profile.build не работает, нужно выбрать ниже, @user.build_profile Некоторые сказали мне, как показано ниже: «если ассоциация была определена с использованием has_one, мы используем функцию «build_association». Для has_many это должно быть «association.build».

person chegoon    schedule 10.10.2014