brayne
brayne

Reputation: 1405

Rails: Nested form with carrierwave

I'm not sure what should go in the controller of the embedded class. The parameters passed does show all the embedded class attributes including image attributes, but only the non-image parameters get saved in the database. This tells me that the issue is not with the choice of ORM (Mongoid in this case) but related to the way I'm using carrier wave:

  Parameters: {"article"=>{"name"=>"New article", "comments_attributes"=>{"0"=>{"remote_image_url"=>"", "name"=>"Comment 1", "content"=>"comment content....", "image"=>#<ActionDispatch::Http::UploadedFile:0x10339d880 @headers="Content-Disposition: form-data; name=\"article[comments_attributes][0][image]\"; filename=\"dh.png\"\r\nContent-Type: image/png\r\n", @original_filename="dh.png", @tempfile=#<File:/var/folders/A1/A1SUPUTUFA8BYB5j+RD2L++++TI/-Tmp-/RackMultipart20120228-21178-1vckii1-0>, @content_type="image/png">}}, "content"=>"article content"}, "commit"=>"Create Article", "authenticity_token"=>"i14YuJs4EVKr5PSEw9IwKXcTbQfOP4mjbR95C75J2mc=", "utf8"=>"\342\234\223"}
MONGODB (89ms) freedb['system.namespaces'].find({})
MONGODB (0ms) freedb['articles'].insert([{"name"=>"New article", "comments"=>[{"name"=>"Comment 1", "_id"=>BSON::ObjectId('4f4daf6a58001652ba000012'), "content"=>"comment content...."}], "_id"=>BSON::ObjectId('4f4daf6958001652ba000011'), "content"=>"article content"}])

Parent model:

class Article
  include Mongoid::Document
  field :name, :type => String
  field :content, :type => String

  embeds_many :comments

  accepts_nested_attributes_for :comments
end

Child model:

require 'carrierwave/mongoid'

class Comment
  include Mongoid::Document
  field :name, :type => String
  field :content, :type => String

  field :image, :required => true
  field :remote_image_url

  embedded_in :article, :inverse_of => :comments
  mount_uploader :image, ImageUploader
end

Parent controller:

  def new
    @article = Article.new
    @article.comments.build
  end

  def create
    @article = Article.new(params[:article])
  end

Parent form:

<%= form_for(@article, :html => {:multipart => true}) do |f| %>

    <div class = "field">
        <%= f.label :name %><br />
        <%= f.text_field :name %>
    </div>

    <%= f.fields_for :comments do |c| %>
    <p>
        <%= c.label :name %>
        <%= c.text_field :name %>
    </p>

    <p>
        <%= c.label :image, "Select Screenshot from your Computer"%><br />
        <%= c.file_field :image %>
    </p>

    <p>
        <%= c.label :remote_image_url, "or URL from the interweb"%><br />
        <%= c.text_field :remote_image_url %>
    </p>

    <% end %>


    <div class = "actions">
        <%= f.submit %>
    </div>
<% end %>

Upvotes: 3

Views: 1207

Answers (1)

shingara
shingara

Reputation: 46914

Carrierwave use some callback to save image and data in your model. By default embedded model have no callback execute. You need say explicitly that your embed need execute his callback.

To do that use the cascade_callbacks: true option.

embeds_many :comments, cascade_callbacks: true

Upvotes: 9

Related Questions