Holger Sindbaek
Holger Sindbaek

Reputation: 2344

Re-upload image with Carrierwave and Nested Form

I have a setup where I have an image class, on which I have an ImageUploader. I'm embedding that class in several different other classes, and uploading images to it with nested form.

Everything is working great, except, once I've uploaded an image, I can't re-upload it again. So I can't press the upload button, and choose another image, like you normally can with carrier wave.

Image Class:

class Image
  # 1. Include mongoid stuff
  include Mongoid::Document
  include Mongoid::Timestamps

  # 2. Mount uploaders
  mount_uploader :image, ImageUploader

  # 3. Define fields
  field :y, type: String, default: "Test"
  field :image
  field :remove_image

  # 4. Set them accessible
  attr_accessible :y, :image, :image_url, :image_cache, :remove_image, :image_cover_url

  # 5. Set associations
  embedded_in :imageable, polymorphic: true
end

Article Class:

class Article
  # 1. Include mongoid stuff
  include Mongoid::Document
  include Mongoid::Timestamps
  include Mongoid::Slug

  # 2. Define fields 
  field :title, type: String
  field :lead, type: String
  field :main_text, type: String

  # 3. Set attributes accesible
  attr_accessible :title, :lead, :main_text, :article_image_attributes

  # 4. Set slug
  slug :title

  # 5. Set associations
  belongs_to :issue
  embeds_one :article_image, :as => :imageable, :class_name => 'Image', cascade_callbacks: true

  # 6. Accepting nested attributes
  accepts_nested_attributes_for :article_image, :allow_destroy => true

  # 7. Set validations
  validates_presence_of :title, :lead, :main_text
  # validate :validate_minimum_article_image_size

  def validate_minimum_article_image_size
    geometry = self.article_image.geometry
    unless geometry.nil?
      width = geometry[0]
      height = geometry[1]

      unless (width >= 1536 && height >= 850)
        errors.add :base, "Article image should minimum be 1536px wide and 850px tall, but was "+width.to_s+"px wide and "+height.to_s+"px tall." 
      end
    end
  end
end

Article controller:

class ArticlesController < ApplicationController
  # 1. Include helpers
  include ApplicationHelper
  include ArticlesHelper

  # 2. Set before filters
  before_filter :authenticate_user!, :unless => :format_whitelist?, :except => [:show]
  before_filter :verify_user
  before_filter :set_objects
  before_filter :set_article

  # 3. Set the responders
  respond_to :html

  # 4. Define and set controllers
  def show
  end

  def new
    @article = @issue.articles.new
    @article.build_article_image
  end

  def edit
    @article.build_article_image unless @article.article_image.present?
  end

  def create
    @article = @issue.articles.new(params[:article])

    if @article.save
      redirect_to magazine_issue_path(@magazine, @issue), notice: 'Article was successfully created.'
    else
      render action: "new", alert: add_errors(@article)
    end
  end

  def update
    if @article.update_attributes(params[:article])
      redirect_to magazine_issue_path(@magazine, @issue), notice: 'Article was successfully updated.'
    else
      render action: "edit", alert: add_errors(@article)
    end
  end

  def destroy
    @article.destroy
    redirect_to :back, notice: 'Article was successfully deleted.'
  end
end

Article form:

= nested_form_for [@magazine, @issue, @article], :validate => true do |f|
  %div.center_big.input_area
    = f.text_field :title, :placeholder => "Title of Article"
    = f.text_area :lead, :placeholder => "Articles leading text", :class => "lead"
    = f.fields_for :article_image do |i| 
      %div.article_image_box.image_box
        = i.link_to_remove "Remove image", :class => "remove_image"
        %span.size.center_big.light.italic Min width and height is 1536px - 850px
        %div.article_image.image
          = image_tag(i.object.image_url) if i.object.image?
        %div.button.grey 
          Choose Article Image (optional)
          = i.file_field :image, :class => "button upload_button"  
          = i.hidden_field :image_cache
    = f.text_area :main_text, :placeholder => "Articles body text", :class => "redactorbox"
    %div= f.submit "Save Article", :disable_with => "Saving...", :class => "button"

Why doesn't the image class just "override" the old image and uploads the new image, like it's supposed to?

Upvotes: 1

Views: 1255

Answers (1)

Holger Sindbaek
Holger Sindbaek

Reputation: 2344

In my update function, I had to specify that I wanted to update my article_image_attributes as well.

So instead of:

if @article.update_attributes(params[:article])

I had to do:

if @article.update_attributes(params[:article]) && @article.article_image.update_attributes(params[:article][:article_image_attributes])

I wasn't able to find this information on any blogs or tutorials, so for the people voting this question down, it would be great if you could help find the answer instead. I'm sure other people have tried to have the same problem as well.

Edit:

Seems like I'm not the only one having this problem - https://github.com/jnicklas/carrierwave-mongoid/pull/64.

Upvotes: 2

Related Questions