I am generating a csv file as a report. It works fine if model validations are passed. In case of failed validations I want to show errors on the "new" action view and keep user there until they correct errors, just like any HTML form. However since I am using format=>'csv' with my form I am getting template missing error when the user input fails model validations.
Missing template /new.html with {:formats=>[:csv],
I tried the following render in my controler but it did not work:
format.csv { render :template=>"new.html.erb"}
I even tried to add a handler in an initializer but did not work:
ActionController::Renderers.add :csv do |csv, options|
self.content_type ||= Mime::CSV
self.response_body = csv.respond_to?(:to_csv) ? csv.to_csv : csv
end
Can you redirect_to you new path in the controller?
redirect_to :action => 'new', :format => 'html'
Related
When using location in respond with, it is ignoring validation errors and redirecting to the specified location. Is this expected behavior?
I checked in the responder module that it checking if there are any errors on the model. I inspected the model and it contains validation errors in the #solution object. What am I missing here?
controller:
def create
#problem = Problem.find(params[:problem_id])
#solution = #problem.solutions.build params[:solution]
#solution.save
respond_with(#solution, :location => detail_problem_solution_path(#problem, #solution)
end
model:
validates :body, :presence => true, :unless => :reference
reference is true or false false.
I encountered this problem today, and come upon this Rails issue over at github. The exception seems to be thrown since the route url helper can't generate a valid for unsaved (invalid) records.
There's discussion on the github issue about allowing procs as an argument to the location parameter, but it doesn't look like it'll be added anytime soon.
For now I'll stick with using the following solution:
def create
#post = Post.new(params[:post])
if #post.save
respond_with(#post, location: edit_post_path(#post))
else
respond_with #post
end
end
The only way I was able to solve is this:
def create
#problem = Problem.find(params[:problem_id])
#solution = #problem.solutions.build solution_params
success = #solution.save
respond_with(#solution) do |format|
format.html {redirect_to detail_problem_solution_path(#problem, #solution) } if success
end
end
how to display error onto another page?
I have a form under user folder
And in another place, my_account folder, i render the form from user folder inside the index page of my_account. so that i can reuse the form,to allow user to update their user information.
So when user click update, update method in UserController will be invoked.
My question is, if faild to update user object, how can i display error message on to my_account index page, and still have the field highlight, and error message??
e.g invalid format of email address
User
-- new.html.erb
-- _form
my_account
-- index.html.erb
I tried to do following, but not sure how can i print the "error" in my_account page:
// try to update user information
// if failed, redirect to my account page
format.html { redirect_to my_account_path, :error => #user.errors }
I'm not sure about it but might work for you.
In update method of user_controller when you get any error just redirect to the index page of my_account and pass the error details with it to be displayed on index page. ie.:
def update
#user = User.find(params[:id])
## update process and if fails
redirect_to :action=> 'index', :status=>:unprocessable_entity, :error=>#user.errors
end
You need the errors to be set on the user object. This is used by form helper to display error messages when calling <%= f.error_messages %> inside your <% form_for %> block.
The Rails best-practice is to call render here, not redirect, so that we ensure we pass the #user object that has errors properly assigned.
To render the action, you can simply call:
if !#user.save
render :action => '../my_account/index'
end
This should easily solve your problem; just make sure to have all of your #member-variables set that the index.html.erb view expects.
I've got a comments form in the article/show page. In this page, it displays the article and has a comments form.
When I submit a comment that has validation errors, I need it to go back to the article/show page, and display the errors there.
Should I change render :action => 'new' to something else?
In the Comment controller, I tried:
def create
...
if #comment.save?
redirect_to article_path(#comment.article), :notice => "Posted comment!"
else
# render :action => 'new'
render 'articles/show"
end
end
But this will complain, since the app won't know which article to show based on the ID.
EDIT: I found this solution. The approach would be to use a session to pass the errors instead. Is this the right way to go with this?
Try this
def create
...
if #comment.save?
redirect_to article_path(#comment.article), :notice => "Posted comment!"
else
# render :action => 'new'
#article = #comment.article
render 'articles/show"
end
end`
So fix your routing so the app does know what article to show based on the ID.
I have a column in a table called Complete that is a boolean.
How can I (using the Rails 3 / JQuery way) provide a link that will toggle that via AJAX?
Historically, I've simply created my own jquery file, grabbed the click event, and done it by hand. But it really seems like I'm missing something by not doing it the "rails" way. If that makes sense.
I guess I still don't understand how the responds_to JS works, JS with ERB, etc.
Is there a good, up-to-date tutorial on how to do this?
Thanks.
see this post,
Rails 3, Custom Actions, and HTML request methods
and use UJS on top of it.
so you have a fallback, if javascript is disabled
a possible method in the controller looks like that:
# GET /surveys/1/close
def close
#survey.close!
flash[:success] = "Survey successfully closed!"
respond_to do |format|
format.html { redirect_to(surveys_url) }
format.xml { head :ok }
format.js { render :partial => 'list_item', :locals => { :survey => #survey } }
end
end
you could also use a state machine to change the state of your object.
I'm trying to implement ajaxy signup with rails 3. I'm using jquery-ujs and remote form. I access the signup form with $.get request, and it is displayed correctly. This signup form is remote:
form_for #user, :remote => true, :html => {"data-type" => "html"} do |f|
In my application.js, if the ajax request for getting the form is successful, I'm trying to bind handler for ajax events from unobtrusive javascript:
var load_remote_form = function(evt) {
var href = $(this).attr('href');
// load form template
$.get(href, {}, function(data) {
$('body').append(data);
$('form[data-remote]').bind("ajax:beforeSend", function(e) {
console.log("Caught beforeSend!");
});
});
evt.preventDefault();
};
$(document).ready(function() {
$('a#signup').click(load_remote_form);
});
Chrome's development tools show that the event "ajax:beforeSend" is binded, but it is never handled (I have nothing in the javascript console when I send the form, though in rails log I see that the request is processed correctly and the response is send). I can bind other events to the same selector (form[data-remote]), like click, and they are handled correctly.
Ajax events binded through .live are not handled as well. But if the form is rendered as part of the layout (i.e. it is on stand-alone page like http://localhost:3000/signup/), binded "ajax:beforeSend" is handled correctly.
My controller (just for a case, it may be badly written, but I'm pretty sure it works):
class UsersController < ApplicationController
layout :layout_for_type
def new
#user = User.new
end
def create
#user = User.new(params[:user])
if #user.save
session[:user_id] = #user.id
flash[:notice] = "You have successfully registered."
redirect_to root_url
else
if request.xhr?
render :action => 'new', :status => :unprocessable_entry, :layout => false
else
render :action => 'new'
end
end
end
def layout_for_type
request.xhr? ? nil : "application"
end
end
What am I doing wrong? May be there is a better approach for implementing such "double-ajaxed" forms?
Silly me. I've completely overlooked another potential source of problems. I had
javascript_include_tag :all
in my application layout, and that caused including both jquery.js and jquery.min.js into my page. It turned out to be the cause of that strange behavior. Removing jquery.min.js did the trick. Hope that might be useful for someone someday.