Cannot upload images with Dropzone.js | Rails 4 and Paperclip - javascript

I'm trying to setup Dropzone in my Rails app to upload multiple images. Dropzone seems to appear on the page fine, but when I submit, the correct url is not uploaded to the database. The JSON returns {"message":"success","fileID":"/images/original/missing.png"}. It's using Paperclip's missing image url.
Picture Model
class Picture < ActiveRecord::Base
belongs_to :album
has_attached_file :image,
:path => ":rails_root/public/images/:id/:filename",
:url => "/images/:id/:filename",
:styles => { :small => "160x160>" }
do_not_validate_attachment_file_type :image
end
Pictures Controller
def create
#picture = Picture.create(picture_params)
if #picture.save
# send success header
render json: { message: "success", fileID: #picture.image.url }, :status => 200
else
# you need to send an error header, otherwise Dropzone
# will not interpret the response as an error:
render json: { error: #picture.errors.full_messages.join(',')}, :status => 400
end
end
pictures.js
$(document).ready(function(){
// disable auto discover
Dropzone.autoDiscover = false;
// grap our upload form by its id
$("#new_picture").dropzone({
// restrict image size to a maximum 1MB
maxFilesize: 1,
// changed the passed param to one accepted by
// our rails app
paramName: "picture[image]",
// show remove links on each image upload
addRemoveLinks: true
});
});
pictures/_form
<%= simple_form_for(#picture, :html => {:class => 'dropzone', multipart: true}) do |f| %>
<%= f.error_notification %>
<div class="form-inputs">
<%= f.input :title %>
<%= f.input :description %>
<%= f.input :album_id %>
</div>
<%= f.label :pictures, :class => 'control-label' %>
<div class="controls">
<%= f.file_field "images[]"%>
</div>
<div class="form-actions">
<%= f.button :submit %>
</div>
<% end %>
Logs
Started POST "/pictures" for ::1 at 2015-01-03 21:49:10 -0500
Value for params[:picture][:images] was set to nil, because it was one of [], [null] or [null, null, ...]. Go to http://guides.rubyonrails.org/security.html#unsafe-query-generation for more information.
Processing by PicturesController#create as JSON
Parameters: {"utf8"=>"✓", "authenticity_token"=>"oM1TCKtz7RGVdJ20qmlYVMXfMuSFylQbRZPkMWlBir8=", "picture"=>{"title"=>"", "description"=>"", "album_id"=>"", "images"=>nil, "image"=>#<ActionDispatch::Http::UploadedFile:0x007ff7d953d7b0 #tempfile=#<Tempfile:/var/folders/_q/9phh0t7s2xnfx_qy82w59thm0000gn/T/RackMultipart20150103-50729-10fo75i>, #original_filename="Space.jpeg", #content_type="image/jpeg", #headers="Content-Disposition: form-data; name=\"picture[image]\"; filename=\"Space.jpeg\"\r\nContent-Type: image/jpeg\r\n">}, "commit"=>"Create Picture"}
Unpermitted parameters: images
Command :: file -b --mime '/var/folders/_q/9phh0t7s2xnfx_qy82w59thm0000gn/T/d511f8439ecde36647437fbba67a439420150103-50729-eoe314.jpeg'
Command :: identify -format '%wx%h,%[exif:orientation]' '/var/folders/_q/9phh0t7s2xnfx_qy82w59thm0000gn/T/d511f8439ecde36647437fbba67a439420150103-50729-1tu8uv1.jpeg[0]' 2>/dev/null
Command :: identify -format %m '/var/folders/_q/9phh0t7s2xnfx_qy82w59thm0000gn/T/d511f8439ecde36647437fbba67a439420150103-50729-1tu8uv1.jpeg[0]'
Command :: convert '/var/folders/_q/9phh0t7s2xnfx_qy82w59thm0000gn/T/d511f8439ecde36647437fbba67a439420150103-50729-1tu8uv1.jpeg[0]' -auto-orient -resize "160x160>" '/var/folders/_q/9phh0t7s2xnfx_qy82w59thm0000gn/T/d511f8439ecde36647437fbba67a439420150103-50729-1tu8uv120150103-50729-5ctpcf'
Command :: file -b --mime '/var/folders/_q/9phh0t7s2xnfx_qy82w59thm0000gn/T/d511f8439ecde36647437fbba67a439420150103-50729-1tu8uv120150103-50729-5ctpcf'
(0.3ms) BEGIN
Command :: file -b --mime '/var/folders/_q/9phh0t7s2xnfx_qy82w59thm0000gn/T/d511f8439ecde36647437fbba67a439420150103-50729-113dzu5.jpeg'
SQL (0.6ms) INSERT INTO "pictures" ("created_at", "description", "image_content_type", "image_file_name", "image_file_size", "image_updated_at", "title", "updated_at") VALUES ($1, $2, $3, $4, $5, $6, $7, $8) RETURNING "id" [["created_at", "2015-01-04 02:49:10.698173"], ["description", ""], ["image_content_type", "image/jpeg"], ["image_file_name", "Space.jpeg"], ["image_file_size", 344179], ["image_updated_at", "2015-01-04 02:49:10.397270"], ["title", ""], ["updated_at", "2015-01-04 02:49:10.698173"]]
(16.6ms) COMMIT
(0.3ms) BEGIN
(0.3ms) COMMIT
Completed 200 OK in 359ms (Views: 0.2ms | ActiveRecord: 18.1ms)
I'm also not sure how to fix the error in the second line of the log, which I think might be the problem.

In your create method, replace:
fileID: #picture.image.url
with:
fileID: #picture.id
you will need fileID to be the id of the upload so you can append it in the js to the delete button of each image.
also do you have images: [] in strong params in your controller? because I believe it should just be :image, also if you do that then in your form replace:
<%= f.file_field "images[]"%>
with:
<%= f.file_field :image, multiple: true %>

In Your JavaScript File
$(document).ready(function()
{
Dropzone.autoDiscover = false;
$("#new_upload").dropzone({
// restrict image size to a maximum 1MB
maxFilesize: 10,
// changed the passed param to one accepted by
// our rails app
paramName: "upload[image]",
// show remove links on each image upload
addRemoveLinks: true,
// if the upload was successful
success: function(file, response){
// find the remove button link of the uploaded file and give it an id
// based of the fileID response from the server
$(file.previewTemplate).find('.dz-remove').attr('id', response.fileID);
// add the dz-success class (the green tick sign)
$(file.previewElement).addClass("dz-success");
}
});
});
in your new.html.erb file
<%= f.file_field :image %><br>
<%= f.submit "Upload" %>
in your controller
def create
#upload = Upload.create(upload_params)
if #upload.save
# send success header
render json: { message: "success", fileID: #upload.id }, :status => 200
else
# you need to send an error header, otherwise Dropzone
# will not interpret the response as an error:
render json: { error: #upload.errors.full_messages.join(',')}, :status => 400
end
end

Related

Error when integrating Actioncable with Rails

I am attempting to build a group chat system where members of the group are able to leave comments in the group's chat section. I am using Actioncable with Rails 5 to implement this in real time, but am unable to overcome a particular hurdle. Chat comments are posted to the database as usual, but there is an error somewhere with the rendering and real-time functionality. Below are all of the affiliated code samples and the error from my terminal. I have been working on this for ages. I am in dire need of enlightenment.
The error: (The entire error message is very long, but this is where the error begins.)
Finished "/cable/" [WebSocket] for 127.0.0.1 at 2018-06-25 18:11:13 -0500
GroupChatCommentsChannel stopped streaming from group:5:group_chat_comments
Started GET "/cable" for 127.0.0.1 at 2018-06-25 18:11:13 -0500
Started GET "/cable/" [WebSocket] for 127.0.0.1 at 2018-06-25 18:11:13 -0500
Successfully upgraded to WebSocket (REQUEST_METHOD: GET, HTTP_CONNECTION: Upgrade, HTTP_UPGRADE: websocket)
GroupChatCommentsChannel is transmitting the subscription confirmation
GroupChatCommentsChannel#follow({"group_id"=>5})
GroupChatCommentsChannel is streaming from group:5:group_chat_comments
Started POST "/groups/5/group_chat_comments" for 127.0.0.1 at 2018-06-25 18:11:50 -0500
Processing by GroupChatCommentsController#create as JS
Parameters: {"utf8"=>"✓", "group_chat_comment"=>{"body"=>"2"}, "commit"=>"Comment", "group_id"=>"5"}
Group Load (0.4ms) SELECT `groups`.* FROM `groups` WHERE `groups`.`id` = 5 LIMIT 1
User Load (0.2ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 1 ORDER BY `users`.`id` ASC LIMIT 1
(0.2ms) BEGIN
Group Load (0.3ms) SELECT `groups`.* FROM `groups` WHERE `groups`.`id` = 5 LIMIT 1
SQL (5.8ms) INSERT INTO `group_chat_comments` (`body`, `user_id`, `group_id`, `created_at`, `updated_at`) VALUES ('2', 1, 5, '2018-06-25 23:11:50', '2018-06-25 23:11:50')
(7.2ms) COMMIT
[ActiveJob] Enqueued RenderGroupChatCommentJob (Job ID: ddceb77d-7c5c-42a3-8570-55d09a569c9e) to Async(default) with arguments: #<GlobalID:0x007f87af0ff7d8 #uri=#<URI::GID gid://news/GroupChatComment/4>>
Rendering group_chat_comments/create.js.erb
Rendered group_chat_comments/_new.html.erb (1.8ms)
Rendered group_chat_comments/create.js.erb (31.6ms)
Completed 200 OK in 201ms (Views: 75.1ms | ActiveRecord: 36.5ms)
GroupChatComment Load (0.2ms) SELECT `group_chat_comments`.* FROM `group_chat_comments` WHERE `group_chat_comments`.`id` = 4 LIMIT 1
[ActiveJob] [RenderGroupChatCommentJob] [ddceb77d-7c5c-42a3-8570-55d09a569c9e] Performing RenderGroupChatCommentJob (Job ID: ddceb77d-7c5c-42a3-8570-55d09a569c9e) from Async(default) with arguments: #<GlobalID:0x007f87ab6a1960 #uri=#<URI::GID gid://news/GroupChatComment/4>>
[ActiveJob] [RenderGroupChatCommentJob] [ddceb77d-7c5c-42a3-8570-55d09a569c9e] Rendered group_chat_comments/_group_chat_comment.html.erb (26.1ms)
[ActiveJob] [RenderGroupChatCommentJob] [ddceb77d-7c5c-42a3-8570-55d09a569c9e] Error performing RenderGroupChatCommentJob (Job ID: ddceb77d-7c5c-42a3-8570-55d09a569c9e) from Async(default) in 60.85ms: ActionView::Template::Error (No route matches {:action=>"show", :controller=>"group_chat_comments", :group_id=>nil, :id=>"4"}, missing required keys: [:group_id]):
The code:
Routes:
resources :groups do
resources :group_chat_comments
end
mount ActionCable.server => '/cable'
Model:
class GroupChatComment < ApplicationRecord
belongs_to :user
belongs_to :group
after_create_commit { RenderGroupChatCommentJob.perform_later self }
end
Controller:
class GroupChatCommentsController < ApplicationController
before_action :set_group
before_action :authenticate_user!
def create
#group_chat_comment = GroupChatComment.create! body: params[:group_chat_comment][:body], group_id: #group.id, user: current_user
end
def destroy
#group_chat_comment = GroupChatComment.find(params[:id])
#group_chat_comment.destroy
redirect_to #group
end
private
def set_group
#group = Group.find(params[:group_id])
end
end
Job:
class RenderGroupChatCommentJob < ApplicationJob
queue_as :default
def perform(group_chat_comment)
ActionCable.server.broadcast "group:#{group_chat_comment.group_id}:group_chat_comments", foo: render_group_chat_comment(group_chat_comment)
end
private
def render_group_chat_comment(group_chat_comment)
ApplicationController.renderer.render(partial: 'group_chat_comments/group_chat_comment', locals: { group_chat_comment: group_chat_comment })
end
end
Channel:
class GroupChatCommentsChannel < ApplicationCable::Channel
def follow(params)
stop_all_streams
stream_from "group:#{params['group_id'].to_i}:group_chat_comments"
end
def unfollow
stop_all_streams
end
end
Channel CoffeeScript:
App.group_chat_comments = App.cable.subscriptions.create "GroupChatCommentsChannel",
collection: -> $('#group_chat_comments')
connected: ->
setTimeout =>
#followCurrentGroup()
, 1000
disconnected: ->
followCurrentGroup: ->
groupId = #collection().data('group-id')
if groupId
#perform 'follow', group_id: groupId
else
#perform 'unfollow'
received: (data) ->
#collection().append(data['group_chat_comment'])
Cable.js:
//= require action_cable
//= require_self
//= require_tree ./channels
(function() {
this.App || (this.App = {});
App.cable = ActionCable.createConsumer();
}).call(this);
The views:
Create.js:
$('#new_group_chat_comment').replaceWith('<%=j render 'group_chat_comments/new', group: #group %>');
_group_chat_comment partial:
<% cache group_chat_comment do %>
<div class="group_chat_comment">
<p>
<%= group_chat_comment.body %>
<%= link_to 'Delete', group_group_chat_comment_path(#group, group_chat_comment), method: :delete %>
</p>
</div>
<% end %>
_group_chat_comments partial:
<%= render 'group_chat_comments/new', group: #group %>
<section id="group_chat_comments" data-group-id="<%= #group.id %>">
<%= render #group.group_chat_comments %>
</section>
_new partial:
<%= form_for [ #group, GroupChatComment.new ], remote: true do |f| %>
<div class="group-comment">
<%= f.text_area :body %>
</div>
<br>
<div class="group-comment-submit">
<%= f.submit 'Comment' %>
</div>
<% end %>

Ajax dynamic select dropdown in rails 5

Trying to populate US county from database by selected state from same table. Trying to implement in Rails 5 using this approach here is the link
So far I was able to figured out and see call being made and proper data return in browser console, but dropdown never gets updated. I was trying to messing around with different routes but still no luck. Please, any help would be appreciated.
#routes
get 'account/main/_update_weather', :to => 'client/main#_update_weather', :as
=> :client_location_java
get 'account/_location', :to => 'client/main#_location', :as =>
:client_location
#controller ../controllers/client/main_controller.rb
def _location
#weathers = Weather.all
#profile = Profile.new
#county_name = Weather.where("state_code = ?", "AL")
end
def _update_weather
#county_name = Weather.where("state_code = ?", params[:state_code])
respond_to do |format|
format.js
end
end
#Ajax /assets/javascripts/location.js.coffee
$ ->
$(document).on 'change', '#state_select', (evt) ->
$.ajax 'main/_update_weather',
type: 'GET'
dataType: 'html'
data: {
state_code: $("#state_select option:selected").val()
}
success: (data, textStatus, jqXHR) ->
console.log("Dynamic county select OK!")
error: (jqXHR, textStatus, errorThrown) ->
console.log("AJAX Error: #{textStatus}")
#View for update ../client/main/_update_weather.html.erb
<script>
$("#county_select").empty()
.append("<%=j render(:partial => #county_name) %>")
</script>
<% #county_name.each do |a| %>
<option value="<%= a.id %>"><%= a.county_name %></option>
<% end %>
#view which trying to update ../client/main/_location.html.erb
<% content_for :head do %>
<%= javascript_include_tag 'location', :media => "all", 'data-turbolinks-
track' => true %>
<% end %>
<%= select_tag "state", options_for_select(state_code) {},
{ id: 'state_select' } %>
<%= f.select :weathers_id, options_for_select(#county_name.collect {|a|
[a.county_name, a.id] }, 0), {}, { id: 'county_select' } %>
#Console output
Started GET "/account/main/_update_weather?state_code=CA" for 127.0.0.1 at 2017-07-17 22:49:11 -0700
User Load (0.3ms) SELECT `users`.* FROM `users` WHERE `users`.`id` = 10 ORDER BY `users`.`id` ASC LIMIT 1
Processing by Client::MainController#_update_weather as HTML
Parameters: {"state_code"=>"CA"}
Rendering client/main/_update_weather.html.erb
Weather Load (3.4ms) SELECT `weathers`.* FROM `weathers` WHERE (state_code = 'CA')
Rendered collection of client/weathers/_weather.js.erb [56 times] (0.7ms)
Rendered client/main/_update_weather.html.erb (8.0ms)
Completed 200 OK in 17ms (Views: 12.0ms | ActiveRecord: 3.4ms)

how to redirect page on submit with Dropzone.js and Rails 4?

I'm using Rails 4, with Paperclip and Dropzone.js. I have a form where users fill in everything and can upload a photo and than submit the form without having Dropzone upload it automatically. So, with the following js It will "put it on hold" until I click the submit button.
items/_form.html.erb
<%= form_for(#item, html: {class: 'form-horizontal form dropzone', multipart: true}) do |f| %>
<%= token_tag(nil) %>
<%= f.file_field :image, class: 'img-input', accept: 'image/png, image/jpeg, image/jpg', multiple: false %>
<%= f.submit 'Done', class: 'btn btn-primary btn-lg btn-block item-submit' %>
<% end %>
items.js
$(document).ready(function() {
// disable auto discover
Dropzone.autoDiscover = false;
var dropzone = new Dropzone (".dropzone", {
maxFiles: 1,
maxFilesize: 1,
paramName: "item[image]",
addRemoveLinks: true,
clickable:'#dropzonePreview',
previewsContainer: '#dropzonePreview',
thumbnailWidth: 300,
thumbnailHeight: 300,
autoProcessQueue: false,
uploadMultiple: false
});
$(".item-submit").click(function (e) {
e.preventDefault();
e.stopPropagation();
dropzone.processQueue();
}
);
});
Routes
resources :items
ItemsController
def new
#item = current_user.items.build
end
def create
#item = current_user.items.build(item_params)
if #item.save
redirect_to #item, notice: "item was successfully created"
else
render 'new'
end
end
The issue I'm having is that I can create a new item and drag n drop a photo but after I submit the form, instead of redirecting to items/show, it will remain on the same page and render the error:
EDITED
Started POST "/items" for 127.0.0.1 at 2015-09-02 15:19:36 -0700
Processing by ItemsController#create as JSON
Parameters: {"utf8"=>"✓", "authenticity_token"=>............
[1m[35m (11.6ms)[0m COMMIT
[1m[33mItem Store (45.9ms)[0m {"id":16}
Redirected to http://localhost:3000/items/16
Completed 302 Found in 2153ms (Searchkick: 45.9ms | ActiveRecord: 13.8ms)
Started GET "/items/16" for 127.0.0.1 at 2015-09-02 15:19:38 -0700
Processing by ItemsController#show as JSON
Parameters: {"id"=>"16"}
[1m[36mItem Load (0.4ms)[0m [1mSELECT "items".* FROM "items" WHERE "items"."id" = $1 LIMIT 1[0m [["id", 16]]
Completed 500 Internal Server Error in 5ms (ActiveRecord: 0.4ms)
ActionView::MissingTemplate - Missing template items/show, application/show with {:locale=>[:en], :formats=>[:json], :variants=>[], :handlers=>[:erb, :builder, :raw, :ruby, :coffee, :jbuilder]}. Searched in:
* "/home/user/dummyappone/app/views"
How can I make it so when my form is submitted, it goes to the show page and still allows the displaying of a flash message and errors if not saved?
Based on comments: just add this to your js:
dropzone.on("success", function(file, responseText) {
window.location.href = ("/items/"+responseText.id)
});
This assumes that dropzone is the dropzone you initialized in your previous JS

JQuery File Upload in Rails - Form still sending HTML requests?

I'm trying to do an asynchronous upload using the following form, but micropost#create is responding to an HTML request. Any advice on how to make my upload form send a JS request?
app/views/shared/_micropost_form.html
<%= form_for #micropost, :html => {:multipart => true} do |f| %>
<%= f.file_field :picture, :multiple => true, :name => "file_folder[picture]" %>
<div><%= f.text_area :content, placeholder: "Caption (Optional)", id: "post-micropost-area" %></div>
<div align="center"><%= f.submit "Post", class: "button postbutton" %></div>
<% end %>
<script>
$(document).ready(function() {
var multiple_photos_form = $('#new_file_folder');
multiple_photos_form.fileupload({dataType: 'script'
add: function (e, data) {
types = /(\.|\/)(gif|jpe?g|png|bmp)$/i;
file = data.files[0];
if (types.test(file.type) || types.test(file.name)) {
data.submit();
}
else { alert(file.name + " must be GIF, JPEG, BMP or PNG file"); }
}
});
});
</script>
app/assets/javascripts/microposts.coffee
(Page with form is rendered by static_pages#home - could that be important?)
jQuery ->
$('#micropost_form').fileupload
dataType: "script"
app/controllers/micropost_controller.rb
def create
#micropost = current_user.microposts.new(micropost_params)
#micropost.hashtags = #micropost.content.scan(/#\w+/).flatten.join(", ")
if #micropost.save
flash[:success] = "Post Created!"
respond_to do |format|
format.html {redirect_to root_url }
format.js
end
else
#feed_items = Micropost.all.paginate(page: params[:page]).per_page(10)
respond_to do |format|
format.html { render 'static_pages/home' }
format.js
end
end
end
[EDIT]
app/views/microposts/create.js.erb
<% if #micropost.new_record? %>
alert("Failed to upload <%=j #micropost.errors.full_messages.join(', ').html_safe %>.")
<% else %>
$('#feed').prepend('<%= j render(#micropost) %>')
<% end %>
$('#micropost_form_div').remove();
$('#new-micropost-link').show();
rails server log
Started POST "/microposts" for 130.95.254.26 at 2015-06-09 07:05:02 +0000
Processing by MicropostsController#create as HTML
Parameters: {"utf8"=>"✓", "authenticity_token"=>"vQQhQEqn3Owt3arYsUTG0u8rrm9AabK7p4xq1N5hCY7SVUU+1oqM82kiEpkys8P+ju4OScp3te15hJOK/yiw5A==", "micropost"=>{"picture"=>[#<ActionDispatch::Http::UploadedFile:0x007f5a808e8fc8 #tempfile=#<Tempfile:/home/ubuntu/workspace/sample_app/RackMultipart20150609-8758-26fuon.png>, #original_filename="bitcomet-logo.png", #content_type="image/png", #headers="Content-Disposition: form-data; name=\"micropost[picture][]\"; filename=\"bitcomet-logo.png\"\r\nContent-Type: image/png\r\n">], "content"=>""}, "commit"=>"Post"}
User Load (0.2ms) SELECT "users".* FROM "users" WHERE "users"."id" = ? ORDER BY "users"."name" ASC LIMIT 1 [["id", 1]]
Unpermitted parameter: picture
(0.1ms) begin transaction
(0.1ms) rollback transaction
Gems (among others)
gem 'carrierwave', '0.10.0'
gem 'mini_magick', '3.8.0'
gem 'jquery-rails', '4.0.3'
gem 'jquery-fileupload-rails'
Try this ......
<%= form_for #micropost, :html => {:multipart => true} do |f| %>
<p>
<%= f.file_field :picture, :multiple => true, :name => "micropost[picture]" %>
</p>
<% end %>
<script>
$(document).ready(function() {
var multiple_photos_form = $('#new_file_folder');
multiple_photos_form.fileupload({dataType: 'script'
add: function (e, data) {
types = /(\.|\/)(gif|jpe?g|png|bmp)$/i;
file = data.files[0];
if (types.test(file.type) || types.test(file.name)) {
data.submit();
}
else { alert(file.name + " must be GIF, JPEG, BMP or PNG file"); }
}
});
});
</script>
Hope this will help you.

Ruby on Rails file uploading using a form with remote: true

I am trying to upload files using a Rails form where the remote is set to true. I'm using Rails 4.1.1. Let's say that my model is a Message, and it is using JavaScript so that the user could easily send multiple messages without reloading the page. The form is set like this:
<%= form_for #message, url: {action: "create"}, html: {:class => "message-form", multipart: true}, remote: true do |f| %>
The user can upload images with the Message, if they wish to do so. MessageImage acts as a nested attribute in the form, and is declared like this (http://railscasts.com/episodes/196-nested-model-form-revised way):
<%= f.fields_for :message_images do |builder| %>
<%= render 'message_image_fields', f: builder %>
<%= link_to_add_fields "Add an image", f, :message_images %>
<% end %>
On my controller the action is roughly like this:
if #message.save
flash.now[:success] = "Message sent"
else
flash.now[:alert] = "Error sending the message"
end
respond_to do |format|
format.html { render 'new' }
format.js { render 'new' }
end
Now, this works perfectly as long as the user doesn't send any images, but if they do, it uses format.html instead of format.js. Removing the format.html gives ActionController::UnknownFormat-exception.
Now, this obviously has to do with the fact that you can't submit files with remote set to true. I tried searching a bit, and found this gem https://github.com/JangoSteve/remotipart , which seems to be exactly what I'm looking for. I installed it following the instructions, but for some reason it still doesn't work and gives ActionController::UnknownFormat-exception if I remove the format.html. However, I couldn't find any example of it involving nested attributes. Are there any alternatives for this gem or any other way to fix this, or should I just set that it renders HTML if the user submits files?
JQuery
I don't know how to get the nested model aspect of this, but we've done file uploading with JQuery / asynchronicity before here (register for account, log into profile):
We used the jquery-file-upload gem - basically allowing you to pass the files through Ajax to your controller backend. To give you a clear idea of how we did this:
--
Code
#app/assets/javascripts/application.js
$('#avatar').fileupload({
url: '/profile/' + $(this).attr('data_id'),
dataType: 'json',
type: 'post',
add: function (e, data) {
$(this).avatar_loading('avatar_loading');
data.submit();
},
success: function (data, status) {;
$("#avatar_img").fadeOut('fast', function() {
$(this).attr("src", data.avatar_url).fadeIn('fast', function(){
$(this).avatar_loading('avatar_loading');
});
});
}
});
#app/views/users/index.html.erb
<%= form_for :upload, :html => {:multipart => true, :id => "avatar"}, :method => :put, url: profile_path(current_user.id), "data_id" => current_user.id do |f| %>
<div class="btn btn-success fileinput-button avatar" id="avatar_container">
<%= f.file_field :avatar, :title => "Upload New" %>
<%= image_tag(#user.profile.avatar.url, :width=> '100%', :id => "avatar_img", :alt => name?(#user)) %>
</div>
<% end %>
#app/controllers/profile_controller.rb
Class ProfileController < ApplicationController
def update
def update
#profile = User.find(current_user.id)
#profile.profile.update(upload_params)
respond_to do |format|
format.html { render :nothing => true }
format.js { render :partial => 'profiles/update.js' }
format.json {
render :json => #profile.profile.as_json(:only => [:id, :avatar], :methods => [:avatar_url])
}
end
def upload_params
params.require(:upload).permit(:avatar, :public, :description)
end
end
end
--
Implementation
For your implementation, I would recommend firstly creating the message, and then getting the user to append some images to it in another action
After you've got that working, you could get it to work as one form

Categories

Resources