I have a form that uploads files via an ajax call (using the remotipart gem), not sure if this is related but when validation fails with file type (using carrierwave white list), I can't get the error message to display in the view, even though other error messages will show (say when file size is to large).
So in my Uploader class
class MediaUploader < CarrierWave::Uploader::Base
def extension_white_list
%w(jpg jpeg gif png docx mp4 pdf)
end
end
So in my form I will attatch a csv file, click submit and the request and responses look like so
Processing by DocumentsController#create as JS
Parameters: {"utf8"=>"✓",
"document"=>
{"skill_id"=>"1",
"media_cache"=>"",
"media"=>#<ActionDispatch::Http::UploadedFile:0x000000070157a0 #tempfile=#<Tempfile:/tmp/RackMultipart20150205-4409-ltyy7t.csv>, #original_filename="csvtest.csv", #content_type="text/csv", #headers="Content-Disposition: form-data; name=\"document[media]\"; filename=\"csvtest.csv\"\r\nContent-Type: text/csv\r\n">},
"commit"=>"Upload",
"remotipart_submitted"=>"true",
"authenticity_token"=>"token here",
"X-Requested-With"=>"IFrame",
"X-Http-Accept"=>"text/javascript, application/javascript, application/ecmascript, application/x-ecmascript, */*; q=0.01"
}
(1.8ms) BEGIN
(2.7ms) ROLLBACK
In my controller I have grabbed the error messages #document.errors
#<ActiveModel::Errors:0x0000000666e418
#base=#
<Document id: nil,
media: nil,
user_id: 1,
skill_id: 1,
created_at: nil,
updated_at: nil>,
#messages={:media=>[
"You are not allowed to upload \"csv\" files, allowed types: jpg, jpeg, gif, png, docx, mp4, pdf",
"At least 1 File is required"
]
}>
After this the relevant controller action/views are called
Rendered documents/_document_form.html.erb (5.1ms)
Rendered documents/create.js.erb (7.7ms)
Completed 200 OK in 167ms (Views: 83.2ms | ActiveRecord: 64.6ms)
My form is set out to iterate through each of the error messages but it doesn't display them
_document_form
<%= form_for #document, remote: true, html: { multipart: true, id: #document.object_id.to_s, class: 'upload_document' } do |f| %>
<% if #document.errors.any? %>
<h2><%= pluralize(#document.errors.count, "error") %> prohibited this record from being saved</h2>
<ul class="error_list">
<% #document.errors.full_messages.each do |msg| %>
<li><%= error_edit(msg) %></li>
<% end %>
</ul>
<% end %>
<%= f.hidden_field :skill_id %>
<%= f.label :media %>
<%= f.file_field :media %>
<%= f.submit 'Upload', class: 'btn btn-success' %>
<div class="js-error"></div>
<% end %>
create action
def create
#document = current_user.documents.new(document_params)
respond_to do |format|
if #document.save
format.html { redirect_to root_path, notice: success_save_msg }
#format.js { render :js => "window.location.href='"+root_path+"'", notice: success_save_msg }
else
format.html
format.js { render action: 'create.js.erb' }
ap(#document.errors)
end
end
end
create.js.erb
$("#<%= #document.skill_id %>").html("<%= j render(partial: 'documents/document_form', locals: { skill_id: #document.skill_id }) %>")
Also I'm looking at the response in the net tab and it's clearly returning the error messages:
<textarea data-type="text/javascript" data-status="200" data-statusText="OK">$
("#1").html("<\n<form id=\"55100200\" class=\"upload_document\" enctype=\"multipart/form-data\" action=\"/documents\" accept-charset=\"UTF-8\" data-remote=\"true\" method=\"post\"><input name=\"utf8\" type=\"hidden\" value=\"✓\" />\n <div id=\"error_explanation\" class=\"alert alert-dismissable\">\n <button type=\"button\" class=\"close\" data-dismiss=\"alert\"><span aria-hidden=\"true\">×<\/span><span class=\"sr-only\">Close<\/span><\/button>\n <h2>2 errors prohibited this record from being saved<\/h2>\n <ul class=\"error_list\">\n <li> You are not allowed to upload "csv" files, allowed types: jpg, jpeg, gif, png, docx, mp4, pdf<\/li>\n <li> At least 1 File is required<\/li>\n <\/ul>\n <\/div>\n\n <input value=\"1\" class=\"skill_id\" type=\"hidden\" name=\"document[skill_id]\" id=\"document_skill_id\" />\n\n <label class=\"custom-file-upload btn btn-info\" for=\"document_media_60835260\">\n <span class=\"glyphicon glyphicon-cloud-upload\"><\/span>\n Find File\n<\/label>\n <input class=\"document_file_field\" id=\"document_media_60835260\" type=\"file\" name=\"document[media]\" />\n <input type=\"hidden\" name=\"document[media_cache]\" id=\"document_media_cache\" />\n\n <input type=\"submit\" name=\"commit\" value=\"Upload\" class=\"btn btn-success\" />\n <div class=\"js-error\"><\/div>\n\n<\/form>")
</textarea>
Can anyone see why the error messages would not display when coming from carrierwave as opposed to a validation from within my Document model?
Thought I Would share this so if anyone else has the same problem it might help. I came across this this Blog. Which then led me to This stackoverflow post.
Turns out i just needed to set the message (or custom message if I wanted) in my en.yml file and carrierwave did the rest
en:
errors:
messages:
extension_white_list_error: 'My Custom Message'
Hope this helps someone
Thats my en.yml
en:
hello: "Hello world"
errors:
messages:
extension_white_list_error: 'My Custom Message'
EDIT This fixed my script
en:
# hello: "Hello world"
errors:
messages:
extension_whitelist_error: "You are not allowed to upload %{extension} files, allowed types: %{allowed_types}"
Related
I have a template to be filled out by a user. My goal is to convert the template into a pdf (containing information supplied by the user) using wicked_pdf.
Also, none of the user input is hitting the model/database. I simply need to convert the template to a pdf containing the user's data, nothing more.
So far, I can convert the template to a pdf, save it and redirect back to my index view. However, none of the fields filled in by the user are saved; all fields that were containing input or values typed by the user are blank. It's simply saving a blank template. How can I convert a pdf and user supplied data to a pdf using wicked_pdf?
# controller save method --->
def save_grade_sheet
#result = Result.find(params[:id])
if current_user.admin?
filename = "#{#result.user.last_name}_grades.pdf"
save_path = "#{Rails.root}/public/uploads/#{#result.user.last_name}/#{filename}"
respond_to do |format|
pdf = render_to_string pdf: filename,
template: "/results/grade_sheet.html.erb",
encoding: "UTF-8",
disposition: "attachment",
save_to_file: save_path,
save_only: true
File.open(save_path, "wb") do |file|
file << pdf
end
flash[:notice] = "#{filename} successfully saved"
format.html { redirect_to results_path }
end
else
head :unauthorized
end
end
# sample template code
<div>
<div>
<h2>PERSONNEL INFORMATION</h2>
<p>Examinee's Name: <%= #result.user.first_name %> <%= #result.user.last_name %></p>
<p>Examiner's Name: <input class="inline" type="text"></p>
</div>
<div>
<p>Exam Type: <%= #result.test.upcase %></p>
<p>Exam Version: <input class="inline" type="text"></p>
<p>Exam Date: <%= #result.created_at.strftime("%m-%d-%y") %></p>
</div>
<%= button_to "Create Grade Sheet", save_grade_sheet_result_path(#result), data: { method: :post }, class: "btn btn-primary btn-lg"%>
</div>
I was sending everything to the correct route, but none of the data was actually being passed. Instead, I needed to wrap everything in a form_tag and use a submit_tag.
<%= form_tag(save_grade_sheet_result_path(#result), method: :post) %>
<div>
<h2>PERSONNEL INFORMATION</h2>
<p>Examiner's Name: <%= text_field_tag :examiner_name, #examiner_name, class: "inline" %></p>
<p>Exam Version:<%= text_field_tag :exam_version, #exam_version, class: "inline" %></p>
</div>
<%= submit_tag "Create Grade Sheet", class: "btn btn-primary btn-lg" %>
<% end %>
And in my controller, I needed to grab the params passed in:
def save_grade_sheet
#result = Result.find(params[:id])
#examiner_name = params[:examiner_name]
#exam_version = params[:exam_version]
if current_user.admin?
# existing code
end
end
I am trying to create an ajax functionality for a sample app of michael heart book . I created a feed model controller which is micropost in hear book . I am trying to use ajax like post feed method . But I am getting some error . I am attaching my code below take a look and help me .
#feeds_controller.erb
class FeedsController < ApplicationController
before_action :authenticate_user! ,only: [:create, :destroy]
def create
#feed = current_user.feeds.build(feed_params)
if #feed.save
flash[:success] = "Micropost created!"
#redirect_to root_url
respond_to do |format|
format.html { redirect_to root_url }
format.js
else
#feed_items = []
render 'static_pages/home'
end
end
def destroy
end
private
def feed_params
params.require(:feed).permit(:content)
end
end
And my home page is rendering some partials Here is the code :
#static_pages/home.html.erb
<% if user_signed_in? %>
<div class="row">
<aside class="col-md-4">
<section class="user_info">
<%= render 'shared/user_info' %>
</section>
<section class="stats">
<%= render 'shared/stats' %>
</section>
</aside>
<div class="col-md-8">
<h3>Micropost Feed</h3>
<section class="micropost_form">
<%= render 'shared/feed_form' %>
</section>
<%= render 'shared/feed' %>
</div>
</div>
<% else %>
<% end %>
Here are two codes Everything work perfectly but when I am trying to add ajax I get the error which is :
Rendered shared/_feed.html.erb (3.1ms)
Rendered feeds/create.js.erb (6.0ms)
Completed 500 Internal Server Error in 73ms (ActiveRecord: 44.4ms)
NoMethodError (undefined method `any?' for nil:NilClass):
app/views/shared/_feed.html.erb:1:in `_app_views_shared__feed_html_erb___516512175__638262078'
app/views/feeds/create.js.erb:1:in `_app_views_feeds_create_js_erb___967625174__637838198'
app/controllers/feeds_controller.rb:9:in `create'
To execute ajax on create method I added these files unders feeds views file name is create.js.erb
$("#feed_add").html("<%= escape_javascript(render partial: "shared/feed") %>");
And form file is under shared view file with name _feed_form.html.erb
<%= form_for(#feed,:remote => true) do |f| %>
<div id="feed_add">
<%= f.text_area :content, placeholder: "Compose new feed..." %>
</div>
<%= f.submit "Post", class: "btn btn-primary" %>
<% end %>
#_feed.html.erb
<% if #feed_items.any? %>
<ol class="microposts">
<%= render #feed_items %>
</ol>
<%= will_paginate #feed_items %>
<% end %>
So tell me how can I add feed and without refreshing how can I show feed using partial In this code .
Here you simply need to render one thing that is feed for that in micheal heart book you simply add this line of code inside your create ajax file here is the code :
$(".microposts").prepend('<%= j render #feed %>');
Here you can get the result what you want .
I have a Rails ajax form to submit.When user will give the correct data it will search the database and do the operation accordingly.If user is giving the Wrong data it should display user to alert message.But it is not happening like that.
I am explaining my codes below.
home.html.erb
<% if current_admin %>
<p class="flash-message"><%=flash[:notice]%></p>
<div class="col-md-6" style="float:none; margin:auto;">
<%= form_for :sdf ,:url => {:action => "scan_report" },remote: true do |f| %>
<% if params[:receipt_no] %>
<div class="input-group bmargindiv1 col-md-12"> <span class="input-group-addon text-left">Receipt No. Scan :</span>
<%= f.text_field :Receipt_No,:class => "form-control", :value => params[:receipt_no] %><%= f.submit "Scan Report" %>
</div>
<% else %>
<div class="input-group bmargindiv1 col-md-12"> <span class="input-group-addon text-left">Receipt No. Scan :</span>
<%= f.text_field :Receipt_No,:class => "form-control",placeholder:"Receipt No. scan" %><%= f.submit "Scan Report" %>
</div>
<% end %>
<% end %>
<% end %>
controller/homes_contorller.rb
class HomesController < ApplicationController
def home
#sdf=TSdf.new
respond_to do |format|
format.html
format.js
end
end
def scan_report
if #sdf=TSdf.find_by_Receipt_No(params[:sdf][:Receipt_No])
if #sdf && #sdf.HCSY_Status=='YES'
#hcsy=THcsy.find_by_Sdp_Id(#sdf.Sdp_Id)
#hcsy_deatils=THcsyDetails.find_by_HCSY_ID(#hcsy.id)
#woods=THcsyFundTypeMaster.find_by_Fund_Type_Code(1)
#burn=THcsyFundTypeMaster.find_by_Fund_Type_Code(2)
#good=THcsyFundTypeMaster.find_by_Fund_Type_Code(3)
#swd=THcsyFundTypeMaster.find_by_Fund_Type_Code(5)
#photo=THcsyFundTypeMaster.find_by_Fund_Type_Code(6)
end
else
flash[:notice]="Not Found"
end
end
end
In this form its only taking the correct input but if user is trying to give the wrong input the else part is not executing.Please help me to resolve this error and let me to know how can i make this ajax call in below format.
$('form').submit(function() {
var valuesToSubmit = $(this).serialize();
$.ajax({
type: "POST",
url: $(this).attr('action'), //sumbits it to the given url of the form
data: valuesToSubmit,
dataType: "JSON" // you want a difference between normal and ajax-calls, and json is standard
}).success(function(json){
console.log("success", json);
});
return false; // prevents normal behaviour
});
Please help me.I am using Rails version 3.2.19.
Here you send AJAX POST request to scan_report, and if it is successful it should render template scan_report.js.erb, and rendered template will appear in json variable in success callback.
But if params are not valid, the same template is rendered, but all instance variables are missing. And probably empty json is returned or an error appears in log.
Anyway, if you'd like to change flash in remote form, you should put custom code in fail callback. Something like
$("#flash").html('<%= j render flash[:notice] %>');
I have trouble displaying error message for invalid inputs using Ruby on rails. If anyone can help me with it? Currently new to the area.
I suspect the area is due to :user and #user.
This is my form generated on index.html.erb
<%= form_for :user, url: '/login', html:{id:"form"} do |f| %>
<h2 class="login">Login</h2>
<div class="form">
<input type="name" placeholder="Name" name="user[name]" class="form-input" required /></div>
<% end %>
My ActiveRecord Model:
class User < ActiveRecord::Base
validates :name, :uniqueness => true
has_secure_password
end
I try to use the following error handling, by passing the following code after <%= form_for :user, url: '/login', html:{id:"form"} do |f| %> but it did not work with and showed:
NoMethodError in Users#register
: undefined method `errors' for nil:NilClass
<% if #user.errors.any? %>
<div id="error_explanation">
<h2><%= pluralize(#article.errors.count, "error") %> prohibited this article from being saved:</h2>
<ul>
<% #user.errors.full_messages.each do |msg| %>
<li><%= msg %></li>
<% end %>
</ul>
</div>
<% end %>
You should be able to do something like this.
/app/views/shared/_error_messages.html.haml:
- if object.errors.any?
.alert.alert-danger
The form contains #{pluralize(object.errors.count, "error")}.
%ul#error_explanation
- object.errors.full_messages.each do |msg|
%li= msg
Then, wherever you want errors to be shown in your views, something like:
= render 'shared/error_messages', object: f.object
Note object in the method. When you call, you could pass either an object instance from your controller or (in the above case), the object of a form builder.
I have some problem with ajax
This request GET http://localhost:3000/projects/new (304 Not Modified) does work, it executes javascript from response:
$('#add-project-button').hide();
$('#project-form').append("<form accept-charset=\"UTF-8\" action=\"/projects\" class=\"new_project\" data-remote=\"true\" id=\"new_project\" method=\"post\"><div style=\"margin:0;padding:0;display:inline\"><input name=\"utf8\" type=\"hidden\" value=\"✓\" /><input name=\"authenticity_token\" type=\"hidden\" value=\"gzu9DETiVV8N+OtRnkdYpD6aa0/RbM7i2H+nkQ0yXGc=\" /><\/div>\n <div class=\"field\">\n <label for=\"project_name\">Name<\/label><br />\n <input id=\"project_name\" name=\"project[name]\" size=\"30\" type=\"text\" />\n <\/div>\n <div class=\"actions\"><input name=\"commit\" type=\"submit\" value=\"Create Project\" /><\/div>\n<\/form>");
But another request POST http://localhost:3000/projects (200 OK) seems ok but response is empty, no javascript is executing, but the server answer is ok:
Rendered tasks/_task.html.erb (0.0ms)
Rendered projects/_project.html.erb (4.5ms)
Rendered shared/_create.js.erb (5.4ms)
Rendered projects/create.js.erb (6.1ms)
Completed 200 OK in 96ms (Views: 8.6ms | ActiveRecord: 84.9ms)
So I'm guessing that the browser somehow is of not supposed to execute javascript from server in this case.
What might be a problem? How to make browser receive the javascript and execute it? Thanks.
UPDATE: The form which is making ajax request:
<%= form_for(#project, :remote => true) do |f| %>
<div class="field">
<%= f.label :name %><br />
<%= f.text_field :name %>
</div>
<div class="actions"><%= f.submit %></div>
<% end %>
The controller action:
def create
#project = current_user.projects.build(params[:project])
respond_with(#project.tap(&:save))
end
Maybe the problem is causing by using partial as layout, projects/create.js.erb:
<% render :layout => '/shared/create', locals: { obj: #project } do %>
$('#project-container').append("<%= escape_javascript render(#project) %>");
$('#add-project-button').show('fast');
$('#project-form').hide('fast', function(){ $('#project-form').empty(); });
<% end %>
The problem was very simple, I forget to put <%= sign in erb, so it should be:
<%= render :layout => '/shared/create', locals: { obj: #project } do %>
$('#project-container').append("<%= escape_javascript render(#project) %>");
$('#add-project-button').show('fast');
$('#project-form').hide('fast', function(){ $('#project-form').empty(); });
<% end %>