Вложенный атрибут Rails удаляется при вызове build
Я очень плохо знаком с Rails, так что, вероятно, здесь есть простая концепция, которую я просто не понимаю, но вот что происходит.
У меня есть модель User (работает на Devise), и у каждого пользователя есть свой соответствующий атрибут фотографии. Я знаю, что мог бы включить фотографию как часть Пользователя, но на самом деле фотографии являются основным содержанием сайта, поэтому я предпочел, чтобы они были их собственной таблицей. Фотомодель имеет вложение скрепки, которое обрабатывает фактический файл фотографии.
Вот проблема: все работает по плану, когда я загружаю фотографию как пользователь, но по какой-то причине, когда я возвращаюсь на страницу загрузки фото, только что загруженная фотография удаляется. Я отследил это до этой строки кода:
@photo = @ user.build_photo
Если я не вызываю это, форма для загрузки выдает ошибку нулевого класса, потому что @user.photo не существует, но когда я действительно вызываю это, она удаляет ранее загруженную фотографию, что странно, потому что Я знаю, что это функция создания, которая изменяет базу данных, а не сборка.
Вот что показывает сервер:
Запуск GET "/settings" для 127.0.0.1 в 2012-03-08 10:19:21 -0800 Обработка с помощью SettingsController#index как пользовательская нагрузка HTML (0,3 мс) SELECT
users
.* ОТusers
ГДЕusers
,id
= 6 ПРЕДЕЛ 1 Загрузка фото (0,3 мс) SELECTphotos
.* ОТphotos
ГДЕphotos
,user_id
= 6 ПРЕДЕЛ 1 (0,2 мс) НАЧАЛО [скрепка] Планирование вложений для удаления. SQL (0,6 мс) УДАЛИТЬ ИЗphotos
ГДЕphotos
,id
= 20 [скрепка] Удаление вложений.
А вот пара моих моделей и контроллеров:
class SettingsController < ApplicationController
def index
@user = current_user
@photo = @user.build_photo
end
end
<h1>Settings Page</h2>
<%= image_tag @user.photo.the_photo.url(:medium) %>
<%= form_for [@user, @photo], :html => { :multipart => true } do |f| %>
<%= f.file_field :the_photo %>
<%= f.submit %>
<% end %>
class User < ActiveRecord::Base
# Include default devise modules. Others available are:
# :token_authenticatable, :encryptable, :confirmable, :lockable, :timeoutable and :omniauthable
devise :database_authenticatable, :registerable,
:recoverable, :rememberable, :trackable, :validatable
# Setup accessible (or protected) attributes for your model
attr_accessible :email, :password, :password_confirmation, :remember_me, :name, :photo_attribute
has_one :photo, :dependent => :destroy
accepts_nested_attributes_for :photo
end
class PhotosController < ApplicationController
def create
@user = current_user
@photo = @user.create_photo(params[:photo])
redirect_to root_path
end
def update
@user = current_user
@photo = @user.photo
if @photo.update_attributes(params[:photo])
redirect_to settings_path
else
redirect_to settings_path
end
end
def destroy
end
end
1 ответ
Как вы обнаружили, звоня @user.build_photo
удалит photo
для этого user
если он уже существует. Вам просто нужно пропустить делать build
в таком случае:
@photo = @user.photo || @user.build_photo