Вложенный атрибут 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 мс) SELECT photos.* ОТ 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
Другие вопросы по тегам